您当前的位置: 首页 >  网络

风间琉璃•

暂无认证

  • 0浏览

    0关注

    337博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

CIFAR10实战(自定义网络)

风间琉璃• 发布时间:2022-02-12 20:10:16 ,浏览量:0

 

CIFAR10 数据集由加拿大 Canadian Institute For Advanced Research 发布,它包含了飞 机、汽车、鸟、猫等共 10 大类物体的彩色图片,每个种类收集了 6000 张32 × 32大小图 片,共 6 万张图片。其中 5 万张作为训练数据集, 1 万张作为测试数据集。

 

一、数据集加载以及数据集的预处理
# 预处理: 类型转换 和归一化
def preprocess(x, y):
    # [0-255] --> [-1, 1]
    x = 2 * tf.cast(x, dtype=tf.float32) / 255. - 1
    y = tf.cast(y, dtype=tf.int32)
    return x, y


batches = 128
# [50k,32,32,3]  [10k,1]
(x, y), (x_val, y_val) =load.load_data()
print(y.shape,y_val.shape)
y = tf.squeeze(y)       # 删除为1的维度,即最后一个维度 [50000,1] ==> [50000]
y_val = tf.squeeze(y_val)

y = tf.one_hot(y, depth=10)  # [50k, 10]
y_val = tf.one_hot(y_val, depth=10)  # [10k,10]
print('datasets:', x.shape, y.shape, x_val.shape, y_val.shape, x.min(), x.max())

# 处理数据集的类型
train_db = tf.data.Dataset.from_tensor_slices((x, y))
train_db = train_db.map(preprocess).shuffle(10000).batch(batches)

test_db = tf.data.Dataset.from_tensor_slices((x_val, y_val))
test_db = test_db.map(preprocess).batch(batches)

sample = next(iter(train_db))
print('batch:', sample[0].shape, sample[1].shape)

CIF10数据集是[60k, 32, 32, 3] 的大小,由于y:[50k,1]要把最后一个维度给去掉,适合于one_hot编码。其他地方和一起处理数据集一样。

二、网络模型构建与装配
# 自定义层
class MyDense(layers.Layer):
    # 代替标准的layers.Dense
    def __init__(self, inp_dim, outp_dim):
        super(MyDense, self).__init__()
        self.kernel = self.add_weight('w', [inp_dim, outp_dim])
        self.bias = self.add_variable('b', [outp_dim])

    def call(self, inputs, training=None):
        x = inputs @ self.kernel
        return x


# 自定义网络
class MyNetwork(keras.Model):
    def __init__(self):
        super(MyNetwork, self).__init__()

        self.fc1 = MyDense(32*32*3, 256)
        self.fc2 = MyDense(256, 128)
        self.fc3 = MyDense(128, 64)
        self.fc4 = MyDense(64, 32)
        self.fc5 = MyDense(32, 10)

    def call(self, inputs, training=None):
        x = tf.reshape(inputs, [-1, 32*32*3])   # 数据打拼为一维
        # [b, 32*32*3] => [b, 256]
        x = self.fc1(x)
        x = tf.nn.relu(x)
        # [b, 256] => [b, 128]
        x = self.fc2(x)
        x = tf.nn.relu(x)
        # [b, 128] => [b, 64]
        x = self.fc3(x)
        x = tf.nn.relu(x)
        # [b, 64] => [b, 32]
        x = self.fc4(x)
        x = tf.nn.relu(x)
        # [b, 32] => [b, 10]
        x = self.fc5(x)

        return x


network = MyNetwork()
network.compile(optimizer=optimizers.Adam(learning_rate=1e-3),
                loss=tf.losses.CategoricalCrossentropy(from_logits=True),
                metrics=['accuracy'])

利用自定义层实现没有偏置的网络层,自定义层要继承于父类layers.Layer。在__init()__里设置权值和偏置。在call()完成该层的向前计算。

网络层设置以后,就可以用它来搭建网络模型 ,自定义网络要继续于父类keras.Model。在__init()__里设置各层的连接,要注意上一层输出维度要于下一层的输入维度相匹配。在call()完成整个网络的向前计算。由于输入的x的三维的(32,32,3),需要将它打平成一维向量。

后面就是类的实例化和为对象设置优化器,损失函数,学习率....

三、训练与测试
network.fit(train_db, epochs=15, validation_data=test_db, validation_freq=1)
network.evaluate(test_db)

 结果:

由于网络全是简单的全连接层,最后的训练结果并不是很理想。

关注
打赏
1665385461
查看更多评论
立即登录/注册

微信扫码登录

0.0395s