放假回家了,感觉快坚持不下去了,目前还没有找到关于无监督学习实现分类的课程,普通数据当然肯定不会给你实现分类的啊 给些建议吧。
LeNet
通过共享卷积核,减少网络参数。
一般只统计卷积计算层和全连接计算层,其余操作是卷积层的附属,
LeNet有五层网络,c1卷积,c3卷积,lenet没有BN操作,没有D
Flatten拉直,连续三层全连接网络,前两层使用sigmod激活函数,左后一层使用softmax。
class LeNer5(Model)
def __init__(self):
super.(LeNet5, eslf).__init__()
# 6个5*5各卷积核激活函数sigmoid
self.c1 = Conv2D(filters=6, kernel_size=(5,5), activation='sigmoid')
#选择最大池化,池化是2*2的尺寸步长为2
self.p1 = MaxPool2D(pool+size=(2, 2), strides=2)
self.c2 = Conv2D(filters=16, kernel_size=(5, 5), activation'sigmoid')
self.p2 = MaxPool2D(pool.size=(2, 2), strides=2)
#拉直
self.flatten = Flatten()
# 全连接网络
self.f1 = Dense(120, activation='sigmod')
self.f2 = Dense(84, activation='sigmoid')
#使输出符合概率分布,10个神经元
self.f3=Dense(10, activation='softmax')
AlexNet
使用Relu激活函数,提升训练速度,dropout缓解过拟合
8层,第一层使用96个3*3个卷积核,步长为1,不适用填充,使用BN操作,实现特征标准化,使用relu激活函数,用3*3的池化核做最大池化,步长为2
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Modelnp.set_printoptions(threshold=np.inf)cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0class AlexNet8(Model):def __init__(self):super(AlexNet8, self).__init__()self.c1 = Conv2D(filters=96, kernel_size=(3, 3))self.b1 = BatchNormalization()self.a1 = Activation('relu')self.p1 = MaxPool2D(pool_size=(3, 3), strides=2)self.c2 = Conv2D(filters=256, kernel_size=(3, 3))self.b2 = BatchNormalization()self.a2 = Activation('relu')self.p2 = MaxPool2D(pool_size=(3, 3), strides=2)self.c3 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',activation='relu')self.c4 = Conv2D(filters=384, kernel_size=(3, 3), padding='same',activation='relu')self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same',activation='relu')self.p3 = MaxPool2D(pool_size=(3, 3), strides=2)self.flatten = Flatten()self.f1 = Dense(2048, activation='relu')self.d1 = Dropout(0.5)self.f2 = Dense(2048, activation='relu')self.d2 = Dropout(0.5)self.f3 = Dense(10, activation='softmax')def call(self, x):x = self.c1(x)x = self.b1(x)x = self.a1(x)x = self.p1(x)x = self.c2(x)x = self.b2(x)x = self.a2(x)x = self.p2(x)x = self.c3(x)x = self.c4(x)x = self.c5(x)x = self.p3(x)x = self.flatten(x)x = self.f1(x)x = self.d1(x)x = self.f2(x)x = self.d2(x)y = self.f3(x)return ymodel = AlexNet8()model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/AlexNet8.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):print('-------------load the model-----------------')model.load_weights(checkpoint_save_path)cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,save_weights_only=True,save_best_only=True)history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])
model.summary()# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:file.write(str(v.name) + '\n')file.write(str(v.shape) + '\n')file.write(str(v.numpy()) + '\n')
file.close()############################################### show ################################################ 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
VGGNet
非常适合硬件加速。
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Modelnp.set_printoptions(threshold=np.inf)cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0class VGG16(Model):def __init__(self):super(VGG16, self).__init__()self.c1 = Conv2D(filters=64, kernel_size=(3, 3), padding='same') # 卷积层1self.b1 = BatchNormalization() # BN层1self.a1 = Activation('relu') # 激活层1self.c2 = Conv2D(filters=64, kernel_size=(3, 3), padding='same', )self.b2 = BatchNormalization() # BN层1self.a2 = Activation('relu') # 激活层1self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')self.d1 = Dropout(0.2) # dropout层self.c3 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')self.b3 = BatchNormalization() # BN层1self.a3 = Activation('relu') # 激活层1self.c4 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')self.b4 = BatchNormalization() # BN层1self.a4 = Activation('relu') # 激活层1self.p2 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')self.d2 = Dropout(0.2) # dropout层self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')self.b5 = BatchNormalization() # BN层1self.a5 = Activation('relu') # 激活层1self.c6 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')self.b6 = BatchNormalization() # BN层1self.a6 = Activation('relu') # 激活层1self.c7 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')self.b7 = BatchNormalization()self.a7 = Activation('relu')self.p3 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')self.d3 = Dropout(0.2)self.c8 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b8 = BatchNormalization() # BN层1self.a8 = Activation('relu') # 激活层1self.c9 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b9 = BatchNormalization() # BN层1self.a9 = Activation('relu') # 激活层1self.c10 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b10 = BatchNormalization()self.a10 = Activation('relu')self.p4 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')self.d4 = Dropout(0.2)self.c11 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b11 = BatchNormalization() # BN层1self.a11 = Activation('relu') # 激活层1self.c12 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b12 = BatchNormalization() # BN层1self.a12 = Activation('relu') # 激活层1self.c13 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')self.b13 = BatchNormalization()self.a13 = Activation('relu')self.p5 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')self.d5 = Dropout(0.2)self.flatten = Flatten()self.f1 = Dense(512, activation='relu')self.d6 = Dropout(0.2)self.f2 = Dense(512, activation='relu')self.d7 = Dropout(0.2)self.f3 = Dense(10, activation='softmax')def call(self, x):x = self.c1(x)x = self.b1(x)x = self.a1(x)x = self.c2(x)x = self.b2(x)x = self.a2(x)x = self.p1(x)x = self.d1(x)x = self.c3(x)x = self.b3(x)x = self.a3(x)x = self.c4(x)x = self.b4(x)x = self.a4(x)x = self.p2(x)x = self.d2(x)x = self.c5(x)x = self.b5(x)x = self.a5(x)x = self.c6(x)x = self.b6(x)x = self.a6(x)x = self.c7(x)x = self.b7(x)x = self.a7(x)x = self.p3(x)x = self.d3(x)x = self.c8(x)x = self.b8(x)x = self.a8(x)x = self.c9(x)x = self.b9(x)x = self.a9(x)x = self.c10(x)x = self.b10(x)x = self.a10(x)x = self.p4(x)x = self.d4(x)x = self.c11(x)x = self.b11(x)x = self.a11(x)x = self.c12(x)x = self.b12(x)x = self.a12(x)x = self.c13(x)x = self.b13(x)x = self.a13(x)x = self.p5(x)x = self.d5(x)x = self.flatten(x)x = self.f1(x)x = self.d6(x)x = self.f2(x)x = self.d7(x)y = self.f3(x)return ymodel = VGG16()model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/VGG16.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):print('-------------load the model-----------------')model.load_weights(checkpoint_save_path)cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,save_weights_only=True,save_best_only=True)history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])
model.summary()# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:file.write(str(v.name) + '\n')file.write(str(v.shape) + '\n')file.write(str(v.numpy()) + '\n')
file.close()############################################### show ################################################ 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
InceptionNet
引入Inception结构块,在同一层网络内内,采用不同的卷积核,提升模型感知力,使用批标准化,缓解梯度消失 结构块分为4个分支,分别经过*1卷积核输出到卷积连接器,经过*1配合3*3输出到卷积连接器,经过1*1配合5*5输出到卷积连接器,经过3*3最大池化核配合1*1卷积核,卷积连接器将各个特征数据按照深度方向进行拼接。
分支1,采用16个1*1,全零填充
分支2,先将16*1*1进行降维,采用BN, 在进行16*3*3卷积核进行操作,
分支3,先降维,在使用16个5*5卷积核
分支4,先池化,降维
CBN操作
通过1*1卷积核,作用到每一个像素点,通过设定少于输入特征图深度的1*1卷积核个数,减少输出特征图的深度,起到了降维的作用,减少参数量和计算量。
使用concat堆叠在一起,axis=3表示堆叠方向
精简的inception网络结构,网络共有10层,第一层采用16个3*3卷积核。
基于cifar数据集是10分类。
将batch_size跳到1024,充分发挥GPU性能,发挥70%到80%
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense, \GlobalAveragePooling2D
from tensorflow.keras import Modelnp.set_printoptions(threshold=np.inf)cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0class ConvBNRelu(Model):def __init__(self, ch, kernelsz=3, strides=1, padding='same'):super(ConvBNRelu, self).__init__()self.model = tf.keras.models.Sequential([Conv2D(ch, kernelsz, strides=strides, padding=padding),BatchNormalization(),Activation('relu')])def call(self, x):x = self.model(x, training=False) #在training=False时,BN通过整个训练集计算均值、方差去做批归一化,training=True时,通过当前batch的均值、方差去做批归一化。推理时 training=False效果好return xclass InceptionBlk(Model):def __init__(self, ch, strides=1):super(InceptionBlk, self).__init__()self.ch = chself.strides = stridesself.c1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c2_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c2_2 = ConvBNRelu(ch, kernelsz=3, strides=1)self.c3_1 = ConvBNRelu(ch, kernelsz=1, strides=strides)self.c3_2 = ConvBNRelu(ch, kernelsz=5, strides=1)self.p4_1 = MaxPool2D(3, strides=1, padding='same')self.c4_2 = ConvBNRelu(ch, kernelsz=1, strides=strides)def call(self, x):x1 = self.c1(x)x2_1 = self.c2_1(x)x2_2 = self.c2_2(x2_1)x3_1 = self.c3_1(x)x3_2 = self.c3_2(x3_1)x4_1 = self.p4_1(x)x4_2 = self.c4_2(x4_1)# concat along axis=channelx = tf.concat([x1, x2_2, x3_2, x4_2], axis=3)return xclass Inception10(Model):def __init__(self, num_blocks, num_classes, init_ch=16, **kwargs):super(Inception10, self).__init__(**kwargs)self.in_channels = init_chself.out_channels = init_chself.num_blocks = num_blocksself.init_ch = init_chself.c1 = ConvBNRelu(init_ch)self.blocks = tf.keras.models.Sequential()for block_id in range(num_blocks):for layer_id in range(2):if layer_id == 0:block = InceptionBlk(self.out_channels, strides=2)else:block = InceptionBlk(self.out_channels, strides=1)self.blocks.add(block)# enlarger out_channels per blockself.out_channels *= 2self.p1 = GlobalAveragePooling2D()self.f1 = Dense(num_classes, activation='softmax')def call(self, x):x = self.c1(x)x = self.blocks(x)x = self.p1(x)y = self.f1(x)return ymodel = Inception10(num_blocks=2, num_classes=10)model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/Inception10.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):print('-------------load the model-----------------')model.load_weights(checkpoint_save_path)cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,save_weights_only=True,save_best_only=True)history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])
model.summary()# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:file.write(str(v.name) + '\n')file.write(str(v.shape) + '\n')file.write(str(v.numpy()) + '\n')
file.close()############################################### show ################################################ 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
ResNet
提出了层间残差跳连,引入前方信息减少梯度消失,是增加网络层数成为可能
通过提升网络层数,有可能会使退化,后面特征丢失了前面特征,
此操作缓解了退化
Inception的+是延深度方向叠加,ResNet块中的+是特征图对应元素值相加(矩阵相加)
ResNet块中有两种情况,一种情况用图中实线表示
加速模型收敛,使模型的batch_size调整到128
import tensorflow as tf
import os
import numpy as np
from matplotlib import pyplot as plt
from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense
from tensorflow.keras import Modelnp.set_printoptions(threshold=np.inf)cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0class ResnetBlock(Model):def __init__(self, filters, strides=1, residual_path=False):super(ResnetBlock, self).__init__()self.filters = filtersself.strides = stridesself.residual_path = residual_pathself.c1 = Conv2D(filters, (3, 3), strides=strides, padding='same', use_bias=False)self.b1 = BatchNormalization()self.a1 = Activation('relu')self.c2 = Conv2D(filters, (3, 3), strides=1, padding='same', use_bias=False)self.b2 = BatchNormalization()# residual_path为True时,对输入进行下采样,即用1x1的卷积核做卷积操作,保证x能和F(x)维度相同,顺利相加if residual_path:self.down_c1 = Conv2D(filters, (1, 1), strides=strides, padding='same', use_bias=False)self.down_b1 = BatchNormalization()self.a2 = Activation('relu')def call(self, inputs):residual = inputs # residual等于输入值本身,即residual=x# 将输入通过卷积、BN层、激活层,计算F(x)x = self.c1(inputs)x = self.b1(x)x = self.a1(x)x = self.c2(x)y = self.b2(x)if self.residual_path:residual = self.down_c1(inputs)residual = self.down_b1(residual)out = self.a2(y + residual) # 最后输出的是两部分的和,即F(x)+x或F(x)+Wx,再过激活函数return outclass ResNet18(Model):def __init__(self, block_list, initial_filters=64): # block_list表示每个block有几个卷积层super(ResNet18, self).__init__()self.num_blocks = len(block_list) # 共有几个blockself.block_list = block_listself.out_filters = initial_filtersself.c1 = Conv2D(self.out_filters, (3, 3), strides=1, padding='same', use_bias=False)self.b1 = BatchNormalization()self.a1 = Activation('relu')self.blocks = tf.keras.models.Sequential()# 构建ResNet网络结构for block_id in range(len(block_list)): # 第几个resnet blockfor layer_id in range(block_list[block_id]): # 第几个卷积层if block_id != 0 and layer_id == 0: # 对除第一个block以外的每个block的输入进行下采样block = ResnetBlock(self.out_filters, strides=2, residual_path=True)else:block = ResnetBlock(self.out_filters, residual_path=False)self.blocks.add(block) # 将构建好的block加入resnetself.out_filters *= 2 # 下一个block的卷积核数是上一个block的2倍self.p1 = tf.keras.layers.GlobalAveragePooling2D()self.f1 = tf.keras.layers.Dense(10, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())def call(self, inputs):x = self.c1(inputs)x = self.b1(x)x = self.a1(x)x = self.blocks(x)x = self.p1(x)y = self.f1(x)return ymodel = ResNet18([2, 2, 2, 2])model.compile(optimizer='adam',loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),metrics=['sparse_categorical_accuracy'])checkpoint_save_path = "./checkpoint/ResNet18.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):print('-------------load the model-----------------')model.load_weights(checkpoint_save_path)cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,save_weights_only=True,save_best_only=True)history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])
model.summary()# print(model.trainable_variables)
file = open('./weights.txt', 'w')
for v in model.trainable_variables:file.write(str(v.name) + '\n')file.write(str(v.shape) + '\n')file.write(str(v.numpy()) + '\n')
file.close()############################################### show ################################################ 显示训练集和验证集的acc和loss曲线
acc = history.history['sparse_categorical_accuracy']
val_acc = history.history['val_sparse_categorical_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()
总结
lenet 卷积网络的开篇之作,共享卷积核,减少网络参数。
AlexNet 使用relu激活函数,提升训练速度,使用Dropout缓解过拟合
VGGnet 小尺寸卷积核,减少参数,网络结构规整,适合并行加速
InceptionNet一层内使用不同尺寸卷积核,提升感知力使用批标准化,缓解梯度消失。