CNN实现离散数据的分类(以图像分类为例)

用CNN实现离散数据的分类(以图像分类为例)

卷积计算

  1. 卷积计算可认为是一种有效提取图像特征的方法
  2. 一般会用一个正方形的卷积核,按指定步长,在输入特征图上滑动。遍历输入特征图中的每一个像素点,每一个步长,卷积核会与输入特征图出现重合区域,重合区域对应元素相乘、求和再加上偏置项得到输入特征的一个像素点
  3. 输入特征图的深度,决定了当前层卷积核的深度
  4. 当前卷积核的个数,决定了当前层输出特征图的深度

感受野

  1. 感受野:卷积神经网络各输出特征图中的每个像素点,在原始输入图片上映射区域等的大小

全零填充(padding)

  1. 卷积计算保持输入特征图的尺寸不变
  2. TF描述全零填充,用参数padding='SAME'padding='VALID'表示

TF描述卷积计算层

tf.keras.layers.Conv2D(
    filters=卷积核个数,
    kernel_size=卷积核尺寸,#正方形写核长整数,或(核高h,核宽w)
    strides=滑动步长,#横纵向相同写步长整数,或(纵向步长h,横向步长w),默认1
    padding="same" or "valid",#使用全零填充是"same",不使用是"valid"(默认)
    activation="relu" or "sigmoid" or "tanh" or "softmax"等,#如有BN此处不写
    input_shape=(高,宽,通道数) #输入特征图维度,可省略
)

举个例子

model=tf.keras.models.Sequential([
    Conv2D(6,5,padding='valid',activation='sigmoid'),
    MaxPool2D(2,2),
    Conv2D(6,(5,5),padding='valid',activation='sigmoid'),
    MaxPool2D(2,2),
    Conv2D(filters=6,kernel_size=(5,5),padding='valid',activation='sigmoid'),
    MaxPool2D(pool_size=(2,2),strides=2),
    Flatten(),
    Dense(10,activation='softmax')
])

批标准化(batch normalization,BN)

  1. 标准化:使数据符合0均值,1为标准差的分布
  2. 批标准化:对一小批数据(batch),做标准化处理,使数据回归标准正态分布,常用在卷积操作和激活操作之间,
  3. 批标准化后,第k个卷积核的输出特征图中第i个像素点满足公式如下
    H^{'k}_{i}=\frac {H^{k}_{i}-\mu^{k}_{batch}}{\sigma^{k}_{batch}}
  • 上述公式中,H^{k}_{i}:批标准化前,第k个卷积核,输出特征图中第i个像素点

  • \mu^{k}_{batch}:批标准化前,第k个卷积核,batch张输出特征图中所有像素点平均值

  • \sigma^{k}_{batch}:批处理化前,第k个卷积核,batch张输出特征图中所有像素点标准差

但是这种简单的特征数据标准化使特征数据完全满足标准正态分布,集中在激活函数中心的线性区域,使激活函数丧失了非线性特性,因此在BN操作中为每个卷积核引入了两个可训练参数,缩放因子\gamma和偏移因子\betax^{k}_{i}=\gamma_k H^{'k}_{i}+\beta_k

反向传播时,缩放因子\gamma和偏移因子\beta会与其他待训练参数一同被训练优化,使标准正态分布后的特征数据通过缩放因子和偏移因子优化了特征数据分布的宽窄和偏移量,保证了网络的非线性表达力

BN层位于卷积层之后,激活层之前

TF描述批标准化tf.keras.layers.BatchNormalization()

model=tf.keras.models.Squential([
    Conv2D(filters=6,kernel_size=(5,5),padding='same'),#卷积层
    BatchNormalization(),#BN层
    Activation('relu'),#激活层
    MaxPool2D(pool_size=(2,2),strides=2,padding='same'),#池化层
    Dropout(0.2), #Dropout层
])

池化(Pooling)

  1. 池化操作用于减少卷积神经网络中特征数据量,池化的主要方法有最大池化和均值池化,最大池化可以提取图片纹理,均值池化可以保留背景特征
  2. TF描述池化
tf,keras.layers.MaxPool2D(
    pool_size=池化核尺寸, #正方形写核长整数,或(核高h,核宽w)
    strides=池化步长, #步长整数,或(纵向步长h,横向步长w),默认为pool_size
    padding='valid' or 'same'#使用全零填充是"same",不使用是"valid"(默认)
)
-------------------------------------------------------------------------
tf.keras.layers.AveragePooling2D(
    pool_size=池化核尺寸,#正方形写核长整数,或(核高h,核宽w)
    strides=池化步长,#步长整数,或(纵向步长h,横向步长w),默认为pool_size
    padding='valid' or 'same' #使用全零填充是"same",不使用是"valid"(默认)
)
--------------------------------------------------------------------------
model=tf.keras.models.Sequential([
    Conv2D(filters=6,kernel_size=(5,5),padding='same'),#卷积层
    BatchNormalization(),#BN层
    Activation('relu'), #激活层
    MaxPool2D(pool_size=(2,2),strides=2,padding='same'),#池化层
    Dropout(0.2),#dropout层
])

舍弃(Dropout)

  1. 为了缓解神经网络过拟合,在神经网络训练过程中,常把隐藏层的部分神经元按照一定比例从神经网络中临时舍弃,在使用神经网络时,再把所有神经元恢复到神经网络中
  2. TF描述舍弃`tf.keras.layers.Dropout(舍弃的概率)
model=tf.keras.models.Sequential([
    Conv2D(filters=6,kernel_size=(5,5),padding='same'),#卷积层
    BatchNormalization(),#BN层
    Activation('relu'), #激活层
    MaxPool2D(pool_size=(2,2),strides=2,padding='same'),#池化层
    Dropout(0.2),#dropout层,0.2表示随机舍弃掉20%的神经元
])

卷积神经网络

  1. 卷积神经网络就是借助卷积核对输入特征进行特征提取,再把提取到的特征送入全连接网络进行识别预测,提取特征包括卷积、批标准化、激活、池化四步,卷积就是特征提取器,就是CBAPD,C代表卷积计算Conv2D,B代表批标准化BN,A代表激活层Avtivation,P代表池化Pooling,D代表舍弃Dropout

cifar10数据集

  1. 提供5万张32*32像素点的十分类彩色图片和标签,用于训练
  2. 提供1万张32*32像素点的十分类彩色图片和标签,用于测试
import tensorflow as tf
from matplotlib import pyplot as plt
import numpy as np

np.set_printoptions(threshold=np.inf)

cifar10 = tf.keras.datasets.cifar10
(x_train, y_train), (x_test, y_test) = cifar10.load_data()

# 可视化训练集输入特征的第一个元素
plt.imshow(x_train[0])  # 绘制图片
plt.show()

# 打印出训练集输入特征的第一个元素
#print("x_train[0]:\n", x_train[0])
# 打印出训练集标签的第一个元素
#print("y_train[0]:\n", y_train[0])

# 打印出整个训练集输入特征形状
print("x_train.shape:\n", x_train.shape)
# 打印出整个训练集标签的形状
print("y_train.shape:\n", y_train.shape)
# 打印出整个测试集输入特征的形状
print("x_test.shape:\n", x_test.shape)
# 打印出整个测试集标签的形状
print("y_test.shape:\n", y_test.shape)
output_1_0.png
x_train.shape:
 (50000, 32, 32, 3)
y_train.shape:
 (50000, 1)
x_test.shape:
 (10000, 32, 32, 3)
y_test.shape:
 (10000, 1)

卷积神经网络搭建示例

卷积过程

  • C(核:6*5*5,步长:1,填充:same)
  • B(yes)
  • A(relu)
  • P(max,核:2*2,步长:2,填充:same)
  • D(0.2)

Flatten

Dense(神经元:128,激活:relu,Dropout:0.2)

Dense(神经元:10,激活:softmax)

实现LeNet、ALexNet、VGGNet、InceptionNet、ResNet五个经典卷积网络

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 Model

np.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.0


class Baseline(Model):
    def __init__(self):
        super(Baseline, self).__init__()
        self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same')  # 卷积层
        self.b1 = BatchNormalization()  # BN层
        self.a1 = Activation('relu')  # 激活层
        self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')  # 池化层
        self.d1 = Dropout(0.2)  # dropout层

        self.flatten = Flatten()
        self.f1 = Dense(128, activation='relu')
        self.d2 = Dropout(0.2)
        self.f2 = 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.d1(x)

        x = self.flatten(x)
        x = self.f1(x)
        x = self.d2(x)
        y = self.f2(x)
        return y


model = Baseline()

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

checkpoint_save_path = "./checkpoint/Baseline.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()
-------------load the model-----------------
Epoch 1/5
1563/1563 [==============================] - 15s 9ms/step - loss: 1.2475 - sparse_categorical_accuracy: 0.5558 - val_loss: 1.4672 - val_sparse_categorical_accuracy: 0.5108
Epoch 2/5
1563/1563 [==============================] - 15s 10ms/step - loss: 1.2192 - sparse_categorical_accuracy: 0.5673 - val_loss: 1.1591 - val_sparse_categorical_accuracy: 0.5880
Epoch 3/5
1563/1563 [==============================] - 15s 10ms/step - loss: 1.1987 - sparse_categorical_accuracy: 0.5734 - val_loss: 1.1963 - val_sparse_categorical_accuracy: 0.5760
Epoch 4/5
1563/1563 [==============================] - 15s 10ms/step - loss: 1.1813 - sparse_categorical_accuracy: 0.5805 - val_loss: 1.1741 - val_sparse_categorical_accuracy: 0.5820
Epoch 5/5
1563/1563 [==============================] - 15s 10ms/step - loss: 1.1692 - sparse_categorical_accuracy: 0.5839 - val_loss: 1.1454 - val_sparse_categorical_accuracy: 0.5940
Model: "baseline_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            multiple                  456       
_________________________________________________________________
batch_normalization_1 (Batch multiple                  24        
_________________________________________________________________
activation_1 (Activation)    multiple                  0         
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 multiple                  0         
_________________________________________________________________
dropout_2 (Dropout)          multiple                  0         
_________________________________________________________________
flatten_1 (Flatten)          multiple                  0         
_________________________________________________________________
dense_2 (Dense)              multiple                  196736    
_________________________________________________________________
dropout_3 (Dropout)          multiple                  0         
_________________________________________________________________
dense_3 (Dense)              multiple                  1290      
=================================================================
Total params: 198,506
Trainable params: 198,494
Non-trainable params: 12
_________________________________________________________________
output_3_1.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349