第五讲 卷积神经网络 VGG16 cifar10

  1 import tensorflow as tf
  2 import os
  3 import numpy as np
  4 from matplotlib import pyplot as plt
  5 from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
  6 from tensorflow.keras import Model
  7 
  8 
  9 np.set_printoptions(threshold=np.inf)
 10 
 11 cifar10 = tf.keras.datasets.cifar10
 12 (x_train, y_train), (x_test, y_test) = cifar10.load_data()
 13 x_train, x_test = x_train/255.0, x_test/255.0
 14 
 15 
 16 class VGG16(Model):
 17   def __init__(self):
 18     super(VGG16, self).__init__()
 19     self.c1 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')
 20     self.b1 = BatchNormalization()
 21     self.a1 = Activation('relu')
 22     self.c2 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')
 23     self.b2 = BatchNormalization()
 24     self.a2 = Activation('relu')
 25     self.p1 = MaxPool2D(pool_size = (2, 2), strides=2, padding='same')
 26     self.d1 = Dropout(0.2)
 27 
 28     self.c3 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')
 29     self.b3 = BatchNormalization()
 30     self.a3 = Activation('relu')
 31     self.c4 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')
 32     self.b4 = BatchNormalization()
 33     self.a4 = Activation('relu')
 34     self.p2 = MaxPool2D(pool_size=(2,2), strides=2, padding='same')
 35     self.d2 = Dropout(0.2)
 36 
 37     self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
 38     self.b5 = BatchNormalization()
 39     self.a5 = Activation('relu')
 40     self.c6 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
 41     self.b6 = BatchNormalization()
 42     self.a6 = Activation('relu')
 43     self.c7 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')
 44     self.b7 = BatchNormalization()
 45     self.a7 = Activation('relu')
 46     self.p3 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
 47     self.d3 = Dropout(0.2)
 48 
 49     self.c8 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 50     self.b8 = BatchNormalization()
 51     self.a8 = Activation('relu')
 52     self.c9 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 53     self.b9 = BatchNormalization()
 54     self.a9 = Activation('relu')
 55     self.c10 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 56     self.b10 = BatchNormalization()
 57     self.a10 = Activation('relu')
 58     self.p4 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')
 59     self.d4 = Dropout(0.2)
 60 
 61     self.c11 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 62     self.b11 = BatchNormalization()
 63     self.a11 = Activation('relu')
 64     self.c12 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 65     self.b12 = BatchNormalization()
 66     self.a12 = Activation('relu')
 67     self.c13 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')
 68     self.b13 = BatchNormalization()
 69     self.a13 = Activation('relu')
 70     self.p5 = MaxPool2D(pool_size=(2,2), strides=2, padding='same')
 71     self.d5 = Dropout(0.2)
 72 
 73     self.flatten = Flatten()
 74     self.f1 = Dense(512, activation='relu')
 75     self.d6 = Dropout(0.2)
 76     self.f2 = Dense(512, activation='relu')
 77     self.d7 = Dropout(0.7)
 78     self.f3 = Dense(10, activation='softmax')
 79 
 80   def call(self, x):
 81     x = self.c1(x)
 82     x = self.b1(x)
 83     x = self.a1(x)
 84     x = self.c2(x)
 85     x = self.b2(x)
 86     x = self.a2(x)
 87     x = self.p1(x)
 88     x = self.d1(x)
 89 
 90     x = self.c3(x)
 91     x = self.b3(x)
 92     x = self.a3(x)
 93     x = self.c4(x)
 94     x = self.b4(x)
 95     x = self.a4(x)
 96     x = self.p2(x)
 97     x = self.d2(x)
 98 
 99     x = self.c5(x)
100     x = self.b5(x)
101     x = self.a5(x)
102     x = self.c6(x)
103     x = self.b6(x)
104     x = self.a6(x)
105     x = self.c7(x)
106     x = self.b7(x)
107     x = self.a7(x)
108     x = self.p3(x)
109     x = self.d3(x)
110 
111     x = self.c8(x)
112     x = self.b8(x)
113     x = self.a8(x)
114     x = self.c9(x)
115     x = self.b9(x)
116     x = self.a9(x)
117     x = self.c10(x)
118     x = self.b10(x)
119     x = self.a10(x)
120     x = self.p4(x)
121     x = self.d4(x)
122 
123     x = self.c11(x)
124     x = self.b11(x)
125     x = self.a11(x)
126     x = self.c12(x)
127     x = self.b12(x)
128     x = self.a12(x)
129     x = self.c13(x)
130     x = self.b13(x)
131     x = self.a13(x)
132     x = self.p5(x)
133     x = self.d5(x)
134 
135     x = self.flatten(x)
136     x = self.f1(x)
137     x = self.d6(x)
138     x = self.f2(x)
139     x = self.d7(x)
140     y = self.f3(x)
141     return y
142 
143 
144 model = VGG16()
145 
146 model.compile(optimizer='adam', 
147               loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
148               metrics=['sparse_categorical_accuracy'])
149 
150 checkpoint_save_path = "./checkpoint/VGG16.ckpt"
151 if os.path.exists(checkpoint_save_path + '.index'):
152   print('------------------------load the model---------------------')
153   model.load_weights(checkpoint_save_path)
154 
155 cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
156                                                  save_weights_only=True,
157                                                  save_best_only=True)
158 
159 
160 history = model.fit(x_train, y_train, batch_size=128, epochs=50, validation_data=(x_test, y_test),validation_freq=1, callbacks=[cp_callback])
161 
162 model.summary()
163 
164 
165 with open('./weights.txt', 'w') as f:
166   for v in model.trainable_variables:
167     f.write(str(v.name) + '\n')
168     f.write(str(v.shape) + '\n')
169     f.write(str(v.numpy()) + '\n')
170 
171 
172 
173 def plot_acc_loss_curve(history):
174     # 显示训练集和验证集的acc和loss曲线
175     from matplotlib import pyplot as plt
176     acc = history.history['sparse_categorical_accuracy']
177     val_acc = history.history['val_sparse_categorical_accuracy']
178     loss = history.history['loss']
179     val_loss = history.history['val_loss']
180     
181     plt.figure(figsize=(15, 5))
182     plt.subplot(1, 2, 1)
183     plt.plot(acc, label='Training Accuracy')
184     plt.plot(val_acc, label='Validation Accuracy')
185     plt.title('Training and Validation Accuracy')
186     plt.legend()
187     #plt.grid()
188     
189     plt.subplot(1, 2, 2)
190     plt.plot(loss, label='Training Loss')
191     plt.plot(val_loss, label='Validation Loss')
192     plt.title('Training and Validation Loss')
193     plt.legend()
194     #plt.grid()
195     plt.show()
196 
197 plot_acc_loss_curve(history)

以下代码源自dive into DL T2.0, 运行时间较长,建议在colab上运行。

  1 import numpy as np
  2 import tensorflow as tf
  3 print(tf.__version__)
  4 
  5 
  6 for gpu in tf.config.experimental.list_physical_devices('GPU'):
  7   tf.config.experimental.set_memory_growth(gpu, True)
  8 
  9 
 10 def vgg_block(num_convs, num_channels):
 11   blk = tf.keras.models.Sequential()
 12   for _ in range(num_convs):
 13     blk.add(tf.keras.layers.Conv2D(num_channels, kernel_size=3, padding='same', activation='relu'))
 14   
 15     blk.add(tf.keras.layers.MaxPool2D(pool_size=2, strides=2))
 16     return blk
 17 
 18 
 19 conv_arch = ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))
 20 
 21 
 22 def vgg(conv_arch):
 23   net = tf.keras.models.Sequential()
 24   for (num_convs, num_channels) in conv_arch:
 25     net.add(vgg_block(num_convs, num_channels))
 26   net.add(tf.keras.models.Sequential([
 27           tf.keras.layers.Flatten(),
 28           tf.keras.layers.Dense(4096, activation='relu'),
 29           tf.keras.layers.Dropout(0.5),
 30           tf.keras.layers.Dense(4096, activation='relu'),
 31           tf.keras.layers.Dropout(0.5),
 32           tf.keras.layers.Dense(10, activation='softmax')
 33   ]))
 34   return net
 35 
 36 net = vgg(conv_arch)
 37 
 38 
 39 X = tf.random.uniform((1, 224, 224, 1))
 40 for blk in net.layers:
 41   X = blk(X)
 42   print(blk.name, 'output shape:\t', X.shape)
 43 
 44 
 45 ratio = 4
 46 small_conv_arch = [(pair[0], pair[1] // ratio) for pair in conv_arch]
 47 net = vgg(small_conv_arch)
 48 
 49 
 50 class DataLoader():
 51   def __init__(self):
 52     fashion_mnist = tf.keras.datasets.fashion_mnist
 53     (self.train_images, self.train_labels), (self.test_images, self.test_labels) = fashion_mnist.load_data()
 54     self.train_images = np.expand_dims(self.train_images.astype(np.float32)/255.0, axis=-1)
 55     self.test_images = np.expand_dims(self.test_images.astype(np.float32)/255.0, axis=-1)
 56     self.train_labels = self.train_labels.astype(np.int32)
 57     self.test_labels = self.test_labels.astype(np.float32)
 58     self.num_train, self.num_test = self.train_images.shape[0], self.test_images.shape[0]
 59   
 60   def get_batch_train(self, batch_size):
 61     index = np.random.randint(0, np.shape(self.train_images)[0], batch_size)
 62     #need to resize images to (224, 224)
 63     resized_images = tf.image.resize_with_pad(self.train_images[index], 224, 224,)
 64     return resized_images.numpy(), self.train_labels[index]
 65   
 66   def get_batch_test(self, batch_size):
 67     index = np.random.randint(0, np.shape(self.test_images)[0], batch_size)
 68     #need to resize images to (224, 224)
 69     resized_images = tf.image.resize_with_pad(self.test_images[index], 224, 224,)
 70     return resized_images.numpy(), self.test_labels[index]
 71 
 72 
 73 batch_size = 128
 74 dataLoader = DataLoader()
 75 x_batch, y_batch = dataLoader.get_batch_train(batch_size)
 76 print('x_batch shape:', x_batch.shape, 'y_batch shape:', y_batch.shape)
 77 
 78 
 79 batch_size = 128
 80 dataLoader = DataLoader()
 81 x_batch, y_batch = dataLoader.get_batch_train(batch_size)
 82 print('x_batch shape:', x_batch.shape, 'y_batch shape:', y_batch.shape)
 83 
 84 
 85 def train_vgg():
 86   #net.load_weights('5.7_vgg_weights.h5)
 87   epoch = 5
 88   num_iter = dataLoader.num_train // batch_size
 89   for e in range(epoch):
 90     for n in range(num_iter):
 91       x_batch, y_batch = dataLoader.get_batch_train(batch_size)
 92       net.fit(x_batch, y_batch)
 93       if n%50 == 0:
 94         net.save_weights('5.7_vgg_weights.h5')
 95 
 96 optimizer = tf.keras.optimizers.SGD(learning_rate = 0.05, momentum=0.0, nesterov=False)
 97 
 98 net.compile(optimizer=optimizer, 
 99             loss='sparse_categorical_crossentropy',
100             metrics=['accuracy'])
101 
102 x_batch, y_batch = dataLoader.get_batch_train(batch_size)
103 net.fit(x_batch, y_batch)
104 train_vgg()
105 
106 
107 net.load_weights('5.7_vgg_weights.h5')
108 
109 x_test, y_test = dataLoader.get_batch_test(2000)
110 net.evaluate(x_test, y_test, verbose=2)