tensorflow 2.0 学习 (十二)卷积神经网络 (二) CIFAR10数据集与改进VGG13网络 + CoLab

网络结构如下:

 代码如下:

  1 # encoding: utf-8
  2 import tensorflow as tf
  3 from tensorflow import keras
  4 from tensorflow.keras import layers, Sequential, losses, optimizers, datasets
  5 import matplotlib.pyplot as plt
  6 
  7 # load data
  8 (x, y), (x_test, y_test) = datasets.cifar10.load_data()
  9 y = tf.squeeze(y, axis=1)
 10 y_test = tf.squeeze(y_test, axis=1)
 11 
 12 
 13 # print(x.shape, y.shape, x_test.shape, y_test.shape)
 14 # (50000, 32, 32, 3) (50000,) (10000, 32, 32, 3) (10000,)
 15 
 16 
 17 def pre_process(X, Y):
 18     x_reshape = tf.cast(X, dtype=tf.float32) / 255.  # 先将类型转化为float32,再归一到0-1
 19     # x = tf.reshape(x, [-1, 32 * 32])                  # 不知道x数量,用-1代替,转化为一维1024个数据
 20     y_reshape = tf.cast(Y, dtype=tf.int32)  # 转化为整型32
 21     y_onehot = tf.one_hot(y_reshape, depth=10)  # 训练数据所需的one-hot编码
 22     return x_reshape, y_onehot
 23 
 24 
 25 # create data_set
 26 train_db = tf.data.Dataset.from_tensor_slices((x, y))
 27 train_db = train_db.shuffle(1000).map(pre_process).batch(128)
 28 
 29 test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
 30 test_db = test_db.shuffle(1000).map(pre_process).batch(128)
 31 
 32 # 观察
 33 # sample = next(iter(train_db))
 34 # print('sample: ', sample[0].shape, sample[1].shape,
 35 #                  tf.reduce_min(sample[0]), tf.reduce_max(sample[0]))
 36 # sample:  (128, 3, 1024) (128, 10)
 37 #           tf.Tensor(0.0, shape=(), dtype=float32)
 38 #           tf.Tensor(1.0, shape=(), dtype=float32)
 39 
 40 
 41 # 卷积子网络
 42 CONV_Net = Sequential([
 43     # 1
 44     layers.Conv2D(64, kernel_size=3, padding='SAME', activation='relu'),
 45     layers.Conv2D(64, kernel_size=3, padding='SAME', activation='relu'),
 46     layers.MaxPooling2D(pool_size=[2, 2], strides=2, padding='SAME'),
 47     # 2
 48     layers.Conv2D(128, kernel_size=3, padding='SAME', activation='relu'),
 49     layers.Conv2D(128, kernel_size=3, padding='SAME', activation='relu'),
 50     layers.MaxPooling2D(pool_size=[2, 2], strides=2, padding='SAME'),
 51     # 3
 52     layers.Conv2D(256, kernel_size=3, padding='SAME', activation='relu'),
 53     layers.Conv2D(256, kernel_size=3, padding='SAME', activation='relu'),
 54     layers.MaxPooling2D(pool_size=[2, 2], strides=2, padding='SAME'),
 55     # 4
 56     layers.Conv2D(512, kernel_size=3, padding='SAME', activation='relu'),
 57     layers.Conv2D(512, kernel_size=3, padding='SAME', activation='relu'),
 58     layers.MaxPooling2D(pool_size=[2, 2], strides=2, padding='SAME'),
 59     # 5
 60     layers.Conv2D(512, kernel_size=3, padding='SAME', activation='relu'),
 61     layers.Conv2D(512, kernel_size=3, padding='SAME', activation='relu'),
 62     layers.MaxPooling2D(pool_size=[2, 2], strides=2, padding='SAME'),
 63 ])
 64 
 65 FC_Net = Sequential([
 66     layers.Dense(256, activation='relu'),
 67     layers.Dense(128, activation='relu'),
 68     layers.Dense(10, activation=None),
 69 ])
 70 
 71 CONV_Net.build(input_shape=[None, 32, 32, 3])
 72 CONV_Net.summary()
 73 
 74 FC_Net.build(input_shape=[None, 512])
 75 FC_Net.summary()
 76 
 77 
 78 def main():
 79     optimizer = tf.keras.optimizers.RMSprop(0.001)  # 创建优化器,指定学习率
 80     criteon = losses.CategoricalCrossentropy(from_logits=True)
 81     Epoch = 50
 82     # 保存训练和测试过程中的误差情况
 83     train_tot_loss = []
 84     test_tot_loss = []
 85 
 86     for epoch in range(Epoch):
 87         cor, tot = 0, 0
 88         for step, (x, y) in enumerate(train_db):  # (128, 32, 32, 3), (128, 10)
 89             with tf.GradientTape() as tape:  # 构建梯度环境
 90                 # train
 91                 out_conv = CONV_Net(x)  # (128, 1, 1, 512)
 92                 out = tf.reshape(out_conv, [-1, 512])  # (128, 512)
 93                 out_fc = FC_Net(out)  # (128, 10) tf.float32
 94 
 95                 # calculate loss
 96                 y = tf.cast(y, dtype=tf.float32)
 97                 loss = criteon(y, out_fc)
 98                 variables = CONV_Net.trainable_variables + FC_Net.trainable_variables
 99                 grads = tape.gradient(loss, variables)
100                 optimizer.apply_gradients(zip(grads, variables))
101 
102                 # train var
103                 train_out = tf.nn.softmax(out_fc, axis=1)
104                 train_out = tf.argmax(train_out, axis=1)
105                 train_out = tf.cast(train_out, dtype=tf.int64)
106 
107                 train_y = tf.nn.softmax(y, axis=1)
108                 train_y = tf.argmax(train_y, axis=1)
109 
110                 # calculate train var loss
111                 train_cor = tf.equal(train_y, train_out)
112                 train_cor = tf.cast(train_cor, dtype=tf.float32)
113                 train_cor = tf.reduce_sum(train_cor)
114                 cor += train_cor
115                 tot += x.shape[0]
116 
117         print('After %d Epoch' % epoch)
118         print('training acc is ', cor / tot)
119         train_tot_loss.append(cor / tot)
120 
121         correct, total = 0, 0
122         for x, y in test_db:
123             # test
124             pred_conv = CONV_Net(x)
125             pred_conv = tf.reshape(pred_conv, [-1, 512])
126             pred = FC_Net(pred_conv)
127 
128             # test var
129             test_out = tf.nn.softmax(pred, axis=1)
130             test_out = tf.argmax(test_out, axis=1)
131             test_out = tf.cast(test_out, dtype=tf.int64)
132 
133             test_y = tf.nn.softmax(y, axis=1)
134             test_y = tf.argmax(test_y, axis=1)
135 
136             test_cor = tf.equal(test_y, test_out)
137             test_cor = tf.cast(test_cor, dtype=tf.float32)
138             test_cor = tf.reduce_sum(test_cor)
139             correct += test_cor
140             total += x.shape[0]
141 
142         print('testing acc is : ', correct / total)
143         test_tot_loss.append(correct / total)
144 
145     plt.figure()
146     plt.plot(train_tot_loss, 'b', label='train')
147     plt.plot(test_tot_loss, 'r', label='test')
148     plt.xlabel('Epoch')
149     plt.ylabel('ACC')
150     plt.legend()
151     # plt.savefig('exam8.3_train_test_CNN1.png')
152     plt.show()
153 
154 
155 if __name__ == "__main__":
156     main()

注释:

(1)由于笔记本配置的原因,程序没有跑完,今后有合适的机器再跑;

(2)对CIFAR数据集的理解不够!需要进一步加深;

(3)下次更新ResNet18网络与CIFAR10数据集实战。

 2020.5.16 --------更新------

(1)采用谷歌CoLab在线跑代码,解决了机器配置不足的问题

训练和测试结果如下:

最后测试准确率到78.95%,与书上77.5%近似。

原文地址:https://www.cnblogs.com/heze/p/12292536.html