第五讲 卷积神经网络 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)