Tensorflow2卷积神经网络的搭建
***** 以下有关代码全是在jupyter notebook 里面调试完后曾,如果直接复制粘贴到pycharm可能不太行,自己得改改
1、卷积神经网络
1、卷积神经网络
CNN最大的特点就是在于卷积的权值共享,利用空间结构减少学习的参数量,防止过拟合的同时减少计算量。在卷积神经网络中,第一个卷积层直接接受图像像素级的输入,卷积之后传给后面的网络,每一层的卷积操作相当于滤波器,对图像进行特征提取,原则上可保证尺度,平移和旋转不变性。
一般的卷积网络包含一下操作:
(1)卷积。图像通过不同卷积核卷积并且加偏置(bias),提取局部特征,每一个卷积核产生一幅新的2D图像。
(2)非线性激活。对卷积输出结果进行非线性激活函数处理,以前常用Sigmoid函数,现在常用ReLU函数。
(3)池化(Pooling)。降采样操作,包括平均池化和最大值池化,一般选择最大值池化,保留最显著特征,提升模型容畸变能力。
(4)完成以上操作之后,就完成了最常见的卷积层。当然也可以加一个LRN(Local Response Nomalization,局部响应归一化)层,目前流行Trick和Batch Nomalization等。
卷积神经网络的好处在于,参数数量只与滤波器数目和卷积核大小有关,与输入图像尺寸无关。总结一下CNN的要点:局部连接,权值共享,池化(降采样)。
2、使用卷积核扫描区域并将卷积核对应位置的参数和扫描区域数值相乘求和得到特征值,扫描多个区域得到多个特征值组合的矩阵就是特征图(feature map)。需要注意的是,卷积操作是针对矩阵区域的,对多个通道的同区域会进行相应合并得到一个特征图(合并一般是分别对每个通道提取特征,然后特征值求和得到该区域的特征)。之所以使用卷积操作提取特征,这是由来已久的,在计算机视觉的历史上使用特定的滤波器处理图片是个常用手段,卷积很早就被提出了,不过那时候对于不同的任务人为设计不同的滤波器(卷积核),这里只是在深度学习的基础上沿用罢了(卷积核变为自动学习而不是人为设计)。
这个过程表现为feature map长宽减小,channel增加,所以卷积神经网络的卷积核数目逐层增加或不变
Fasion_minst识别卷积神经网络搭建代码
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
(train_images,train_labels),(test_images,test_labels)=tf.keras.datasets.fashion_mnist.load_data() #加载图片数据
#下载下来的图片的shape为(60000,28,28)
train_images=np.expand_dims(train_images,-1) #将训练图片增加一个维度(60000,28,28,1)最后一个数字代表的是图片的通道数为1
test_images=np.expand_dims(test_images,-1)
model=tf.keras.Sequential() #建立顺序模型
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=(28,28,1),activation="relu",padding="same"))
#第一层采用卷积核数目为64,卷积核大小(3,3),卷积神经网络可以图片直接输入,不需要Flatten,输入图片的shape为(28,28,1),激活函数:relu,padding填充方式采用“same”方式,希望卷积后不改变图片的长和宽
#此时模型的图片输出shape为 (None, 28, 28, 64)
model.add(tf.keras.layers.Conv2D(64,(3,3),activation="relu",padding="same"))
#再同样进行特征提取
#此时模型的图片输出shape为 (None, 28, 28, 64)
model.add(tf.keras.layers.MaxPool2D()) #进行Maxpooling池化,默认的pool_size为(2, 2),就是图片的长宽减少一半
#此时模型的图片输出shape为 (None, 14, 14, 64)
model.add(tf.keras.layers.Dropout(0.5)) #防止过拟合,丢弃一半(0.5)
#此时模型的图片输出shape为 (None, 14, 14, 64)
model.add(tf.keras.layers.Conv2D(128,(3,3),activation="relu",padding="same"))
#此时模型的图片输出shape为(None, 14, 14, 128)
model.add(tf.keras.layers.Conv2D(128,(3,3),activation="relu",padding="same"))
#此时模型的图片输出shape为(None, 14, 14, 128)
model.add(tf.keras.layers.MaxPool2D())
#此时模型的图片输出shape为(None, 7, 7, 128)
model.add(tf.keras.layers.Dropout(0.5)) #防止过拟合
model.add(tf.keras.layers.Conv2D(256,(3,3),activation="relu",padding="same"))
#此时模型的图片输出shape为(None, 7, 7, 256)
model.add(tf.keras.layers.Conv2D(256,(3,3),activation="relu",padding="same"))
#此时模型的图片输出shape为(None, 7, 7, 256)
model.add(tf.keras.layers.MaxPool2D())
#此时模型的图片输出shape为(None, 3, 3, 256)
model.add(tf.keras.layers.Dropout(0.5)) #防止过拟合
model.add(tf.keras.layers.Conv2D(512,(3,3),activation="relu",padding="same"))
model.add(tf.keras.layers.Conv2D(512,(3,3),activation="relu",padding="same"))
#此时模型的图片输出shape为(None, 3, 3, 512)
model.add(tf.keras.layers.Dropout(0.5)) #防止过拟合
model.add(tf.keras.layers.MaxPool2D())
#此时模型的图片输出shape为(None, 1, 1, 512)
model.add(tf.keras.layers.GlobalAveragePooling2D())
#通过GlobalAveragePooling2D()和后面的Dense层好连接,此时模型的图片输出shape为(None, 512)
model.add(tf.keras.layers.Dense(256,activation="relu")) #此时模型的图片输出shape为(None, 256)
model.add(tf.keras.layers.Dense(10,activation="softmax")) #此时模型的图片输出shape为(None, 10)
model.compile(optimizer="adam",loss="sparse_categorical_crossentropy",metrics=["acc"])
history=model.fit(train_images,train_labels,epochs=30,validation_data=(test_images,test_labels)) #将训练数据记录到history中
history.history.keys() #查看history字典中存在的一些元素,输出为dict_keys(['loss', 'acc', 'val_loss', 'val_acc'])
#下面来进行图形的绘制
plt.plot(history.epoch,history.history.get("loss"),history.history.get("val_loss")) #图一
plt.plot(history.epoch,history.history.get("acc"),history.history.get("val_acc")) #图二
图一:训练集上的loss变化和测试集上的loss
图二:训练集上的准确度变化和测试集上的准确度变化
训练过程:
Train on 60000 samples, validate on 10000 samples
Epoch 1/30
60000/60000 [==============================] - 32s 528us/sample - loss: 0.8797 - acc: 0.6702 - val_loss: 0.6335 - val_acc: 0.8100
Epoch 2/30
60000/60000 [==============================] - 30s 496us/sample - loss: 0.5320 - acc: 0.8024 - val_loss: 0.4684 - val_acc: 0.8325
Epoch 3/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4778 - acc: 0.8247 - val_loss: 0.4498 - val_acc: 0.8327
Epoch 4/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4612 - acc: 0.8302 - val_loss: 0.4428 - val_acc: 0.8462
Epoch 5/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4476 - acc: 0.8348 - val_loss: 0.4148 - val_acc: 0.8534
Epoch 6/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4323 - acc: 0.8411 - val_loss: 0.4233 - val_acc: 0.8494
Epoch 7/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4417 - acc: 0.8386 - val_loss: 0.4293 - val_acc: 0.8348
Epoch 8/30
60000/60000 [==============================] - 30s 495us/sample - loss: 0.4405 - acc: 0.8369 - val_loss: 0.4191 - val_acc: 0.8505
Epoch 9/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4319 - acc: 0.8442 - val_loss: 0.4399 - val_acc: 0.8426
Epoch 10/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4291 - acc: 0.8442 - val_loss: 0.4105 - val_acc: 0.8528
Epoch 11/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4352 - acc: 0.8438 - val_loss: 0.4030 - val_acc: 0.8445
Epoch 12/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4272 - acc: 0.8454 - val_loss: 0.3890 - val_acc: 0.8490
Epoch 13/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4218 - acc: 0.8457 - val_loss: 0.4146 - val_acc: 0.8504
Epoch 14/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4279 - acc: 0.8436 - val_loss: 0.4110 - val_acc: 0.8471
Epoch 15/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4367 - acc: 0.8435 - val_loss: 0.4038 - val_acc: 0.8605
Epoch 16/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4261 - acc: 0.8466 - val_loss: 0.4207 - val_acc: 0.8493
Epoch 17/30
60000/60000 [==============================] - 30s 497us/sample - loss: 0.4331 - acc: 0.8471 - val_loss: 0.4066 - val_acc: 0.8508
Epoch 18/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4203 - acc: 0.8499 - val_loss: 0.3957 - val_acc: 0.8670
Epoch 19/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4375 - acc: 0.8461 - val_loss: 0.4205 - val_acc: 0.8559
Epoch 20/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.5291 - acc: 0.8211 - val_loss: 0.3844 - val_acc: 0.8631
Epoch 21/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4633 - acc: 0.8358 - val_loss: 0.4324 - val_acc: 0.8429
Epoch 22/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.5239 - acc: 0.8174 - val_loss: 0.4334 - val_acc: 0.8423
Epoch 23/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4857 - acc: 0.8284 - val_loss: 0.4756 - val_acc: 0.8329
Epoch 24/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4577 - acc: 0.8358 - val_loss: 0.4016 - val_acc: 0.8562
Epoch 25/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4908 - acc: 0.8299 - val_loss: 0.4884 - val_acc: 0.8416
Epoch 26/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4648 - acc: 0.8373 - val_loss: 0.4129 - val_acc: 0.8594
Epoch 27/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4702 - acc: 0.8356 - val_loss: 0.4004 - val_acc: 0.8544
Epoch 28/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4374 - acc: 0.8433 - val_loss: 0.4272 - val_acc: 0.8548
Epoch 29/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4997 - acc: 0.8320 - val_loss: 0.4436 - val_acc: 0.8439
Epoch 30/30
60000/60000 [==============================] - 30s 498us/sample - loss: 0.4679 - acc: 0.8372 - val_loss: 0.4321 - val_acc: 0.8589
2、卫星图像识别卷积综合实例
(以下代码全部在jupyter notebook调试)
1) 图片的数据读取部分
#利用tf.data来提取图片,将用作图片的输入,然后输入到卷积神经网络中,对这个图片进行识别
import tensorflow as tf
import matplotlib.pyplot as plt
%matplotlib inline
import pathlib #面向对象的路径管理工具
import random
data_dir="./2_class" #,创建一个路径文件,数据在当前目录下的2_class下面
#构造一个data_root路径对象
data_root=pathlib.Path(data_dir) #data_root有很多的方法来帮助我们提取里面的路径 data_root输出——WindowsPath('2_class')
for item in data_root.iterdir():
print(item) #对目录进行迭代,就可以取出所有的路径出来
# 输出:2_class\airplane 2_class\lake
all_image_path=list(data_root.glob("*/*")) #提取所有的路径,无论他的目录是什么,所有目录的所有文件,取出来的是一个可迭代的对象,使用list方法将其变成一个列表
#得到了所有的路径,但是是一个windows path的路径
#用一个列表推导式,将windows path变成实际的路径,str(path)代表的是真是的路径,然后迭代输出
all_image_path=[str(path) for path in all_image_path]
#for path in all_image_path:
# print(path) ——输出:2_class\airplane\airplane_001.jpg...
#str(path):'2_class\\airplane\\airplane_001.jpg"...
#
#
#all_image_path #前700是airplane 后700是lake 需要乱序
# ['2_class\\airplane\\airplane_001.jpg',
# '2_class\\airplane\\airplane_002.jpg',
# '2_class\\airplane\\airplane_003.jpg',
# '2_class\\airplane\\airplane_004.jpg',...
random.shuffle(all_image_path) #对所有的路径进行乱序
image_count=len(all_image_path) #所有的图片的数目
#提取类名
label_names=sorted(item.name for item in data_root.glob("*/")) #['airplane', 'lake'] 这是一个列表,0是airplane 1是lake
# for index,name in enumerate(label_names):
# print(index,name) #0 airplane 1 lake
#转换成编码
label_to_index=dict((name,index) for index,name in enumerate(label_names)) #{'airplane': 0, 'lake': 1}
2)读取和解码图片
# pathlib.Path('2_class\\lake\\lake_248.jpg').parent.name —————————— 输出为lake
#先构造pathlib对象,再取出他的parent.name ,然后转化成相应的编码 ,为了得到所有图片的标签,就是他的上一级文件的文件夹名字
all_image_label=[label_to_index[pathlib.Path(p).parent.name] for p in all_image_path]
# all_image_label[:5] —— [1, 0, 1, 1, 1]
# label_to_index.items() ————输出dict_items([('airplane', 0), ('lake', 1)])
# for k,v in label_to_index.items():
# print(k,v)——————————————输出0 airplane 1 lake
index_to_label=dict((v,k) for k,v in label_to_index.items() ) #知道label想获取实际的名字
# index_to_label——————————————输出:{0: 'airplane', 1: 'lake'}
import IPython.display as display
for n in range(3):
image_index=random.choice(range(len(all_image_path))) #从len(all_image_path)这么多图片里,每次迭代,选取一张
display.display(display.Image(all_image_path[image_index]))#展示第image_index路径的图片
print(index_to_label[all_image_label[image_index]])
print()
输出:
3)图片预处理(读取,解码,标准化…)
# #读取单张图片
# img_path=all_image_path[0] #得到一个路径
# # img_path————输出:'2_class\\lake\\lake_248.jpg'
# #读取进来是一个二进制的数据
# img_raw=tf.io.read_file(img_path) #是一个tensor array
# #解码图片
# img_tensor=tf.image.decode_image(img_raw) #解码得到的tensor
# # img_tensor.shape
# # ————TensorShape([256, 256, 3])
# # img_tensor.dtype #图片的数据类型就是uint8 (0-255)
# # ————tf.uint8
#对输入到神经网络的图片先做一个标准化,比较简单的就是将图片除以255
# img_tensor=tf.cast(img_tensor,tf.float32) #将数据类型转换成tf.float32数据类型
# img_tensor=img_tensor/255 #标准化
# img_tensor.numpy().max() 0.8039216
# img_tensor.numpy().min() 0.0
# 图片预处理函数****************
def load_preprocess_imge(img_path):
#读取进来是一个二进制的数据
img_raw=tf.io.read_file(img_path) #是一个tensor array
#解码图片
img_tensor=tf.image.decode_jpeg(img_raw,channels=3) #解码得到的tensor,解析的是一张彩色图片
img_tensor=tf.image.resize(img_tensor,[256,256])#resize会产生变形
#对输入到神经网络的图片先做一个标准化,比较简单的就是将图片除以255
img_tensor=tf.cast(img_tensor,tf.float32) #将数据类型转换成tf.float32数据类型
img=img_tensor/255 #标准化
return img
image_path=all_image_path[500]
plt.imshow(load_preprocess_imge(image_path))
plt.imshow(load_preprocess_imge(image_path))输出:
4) 构造tf.data数据集
#构造tf.data
path_ds=tf.data.Dataset.from_tensor_slices(all_image_path) #使用all_image_path建立了一个path_ds
#返回一个<TensorSliceDataset shapes: (), types: tf.string>
#每一张图片都是从0到1的一个tensor array,已经处理好了
#image_dataset都是tensor
image_dataset=path_ds.map(load_preprocess_imge)
label_ds=tf.data.Dataset.from_tensor_slices(all_image_label) #label_ds比较单纯,不需要我们做额外的预处理就是编码的0,1
# for img in image_dataset.take(1):
# print(img)
# for label in label_ds.take(5): #取前五个
# print(label.numpy())
# image_dataset 输出:<MapDataset shapes: (256, 256, 3), types: tf.float32>
#划分为train数据和test数据
test_count= int(image_count*0.2)
train_cout=image_count-test_count
#如何划分?
train_dataset=dataset.skip(test_count) #这个数据集跳过test_count的数目
test_dataset=dataset.take(test_count) #对于test数据集,take出test_count的数据
#希望数据是乱序的,无限重复的,batch的
BATCH_SIZE=32 #一个训练批次多少张图片
#此处数据集先乱序,无限重复,可以让数据一直产生数据,每一个批次32个图片
#在多大的范围(buffer_size)内进行shuffle
train_dataset=train_dataset.shuffle(buffer_size=train_cout).repeat().batch(BATCH_SIZE)
test_dataset=test_dataset.batch(BATCH_SIZE) #测试集不需要太多的操作
5)模型的构建与训练
model=tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=(256,256,3),activation="relu"))
model.add(tf.keras.layers.Conv2D(64,(3,3),activation="relu"))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(128,(3,3),activation="relu"))
model.add(tf.keras.layers.Conv2D(128,(3,3),activation="relu"))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(256,(3,3),activation="relu"))
model.add(tf.keras.layers.Conv2D(256,(3,3),activation="relu"))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(512,(3,3),activation="relu"))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(512,(3,3),activation="relu"))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(1024,(3,3),activation="relu"))
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(1024,activation="relu"))
model.add(tf.keras.layers.Dense(256,activation="relu"))
model.add(tf.keras.layers.Dense(10,activation="relu"))
model.add(tf.keras.layers.Dense(1,activation="sigmoid"))
model.summary() #可训练参数非常多
Model: "sequential_13"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_52 (Conv2D) (None, 254, 254, 64) 1792
_________________________________________________________________
conv2d_53 (Conv2D) (None, 252, 252, 64) 36928
_________________________________________________________________
max_pooling2d_28 (MaxPooling (None, 126, 126, 64) 0
_________________________________________________________________
conv2d_54 (Conv2D) (None, 124, 124, 128) 73856
_________________________________________________________________
conv2d_55 (Conv2D) (None, 122, 122, 128) 147584
_________________________________________________________________
max_pooling2d_29 (MaxPooling (None, 61, 61, 128) 0
_________________________________________________________________
conv2d_56 (Conv2D) (None, 59, 59, 256) 295168
_________________________________________________________________
conv2d_57 (Conv2D) (None, 57, 57, 256) 590080
_________________________________________________________________
max_pooling2d_30 (MaxPooling (None, 28, 28, 256) 0
_________________________________________________________________
conv2d_58 (Conv2D) (None, 26, 26, 512) 1180160
_________________________________________________________________
max_pooling2d_31 (MaxPooling (None, 13, 13, 512) 0
_________________________________________________________________
conv2d_59 (Conv2D) (None, 11, 11, 512) 2359808
_________________________________________________________________
max_pooling2d_32 (MaxPooling (None, 5, 5, 512) 0
_________________________________________________________________
conv2d_60 (Conv2D) (None, 3, 3, 1024) 4719616
_________________________________________________________________
global_average_pooling2d_6 ( (None, 1024) 0
_________________________________________________________________
dense_24 (Dense) (None, 1024) 1049600
_________________________________________________________________
dense_25 (Dense) (None, 256) 262400
_________________________________________________________________
dense_26 (Dense) (None, 10) 2570
_________________________________________________________________
dense_27 (Dense) (None, 1) 11
=================================================================
Total params: 10,719,573
Trainable params: 10,719,573
Non-trainable params: 0
_________________________________________________________________
模型的配置:
model.compile(optimizer="adam",loss="binary_crossentropy",metrics=["acc"])
每一个epoch设置的运行步数,训练的时候要告诉他多少步是一个epoch,这个dataset会无限制的去输出,一个batch是多少步
steps_per_epoch=train_cout//BATCH_SIZE
validation_steps=test_count//BATCH_SIZE
模型的训练:
history=model.fit(train_dataset,epochs=30,steps_per_epoch=steps_per_epoch,validation_data=test_dataset,validation_steps=validation_steps)
输出信息:
Train for 35 steps, validate for 8 steps
Epoch 1/30
35/35 [==============================] - 25s 714ms/step - loss: 0.5690 - acc: 0.7384 - val_loss: 0.3976 - val_acc: 0.8906
Epoch 2/30
35/35 [==============================] - 14s 404ms/step - loss: 0.1658 - acc: 0.9589 - val_loss: 0.1714 - val_acc: 0.9492
Epoch 3/30
35/35 [==============================] - 14s 405ms/step - loss: 0.1296 - acc: 0.9696 - val_loss: 0.1659 - val_acc: 0.9492
Epoch 4/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1330 - acc: 0.9571 - val_loss: 0.1404 - val_acc: 0.9492
Epoch 5/30
35/35 [==============================] - 14s 405ms/step - loss: 0.1205 - acc: 0.9688 - val_loss: 0.1329 - val_acc: 0.9531
Epoch 6/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1072 - acc: 0.9696 - val_loss: 0.1314 - val_acc: 0.9609
Epoch 7/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1117 - acc: 0.9652 - val_loss: 0.1350 - val_acc: 0.9414
Epoch 8/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1509 - acc: 0.9625 - val_loss: 0.2358 - val_acc: 0.9141
Epoch 9/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1604 - acc: 0.9500 - val_loss: 0.1514 - val_acc: 0.9492
Epoch 10/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1485 - acc: 0.9580 - val_loss: 0.1339 - val_acc: 0.9648
Epoch 11/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0962 - acc: 0.9786 - val_loss: 0.1077 - val_acc: 0.9609
Epoch 12/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0872 - acc: 0.9795 - val_loss: 0.2099 - val_acc: 0.9570
Epoch 13/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0782 - acc: 0.9795 - val_loss: 0.1167 - val_acc: 0.9648
Epoch 14/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0926 - acc: 0.9830 - val_loss: 0.1960 - val_acc: 0.9648
Epoch 15/30
35/35 [==============================] - 14s 407ms/step - loss: 0.0859 - acc: 0.9750 - val_loss: 0.1163 - val_acc: 0.9688
Epoch 16/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0762 - acc: 0.9777 - val_loss: 0.1215 - val_acc: 0.9609
Epoch 17/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0705 - acc: 0.9839 - val_loss: 0.1088 - val_acc: 0.9688
Epoch 18/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0571 - acc: 0.9830 - val_loss: 0.1043 - val_acc: 0.9688
Epoch 19/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0804 - acc: 0.9777 - val_loss: 0.2600 - val_acc: 0.9570
Epoch 20/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1020 - acc: 0.9670 - val_loss: 0.1407 - val_acc: 0.9688
Epoch 21/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0880 - acc: 0.9812 - val_loss: 0.1337 - val_acc: 0.9727
Epoch 22/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0880 - acc: 0.9759 - val_loss: 0.3044 - val_acc: 0.9766
Epoch 23/30
35/35 [==============================] - 14s 406ms/step - loss: 0.1375 - acc: 0.9571 - val_loss: 0.1364 - val_acc: 0.9609
Epoch 24/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0987 - acc: 0.9768 - val_loss: 0.1306 - val_acc: 0.9727
Epoch 25/30
35/35 [==============================] - 14s 406ms/step - loss: 0.0727 - acc: 0.9804 - val_loss: 0.1004 - val_acc: 0.9727
Epoch 26/30
35/35 [==============================] - 14s 405ms/step - loss: 0.0541 - acc: 0.9875 - val_loss: 0.1214 - val_acc: 0.9805
Epoch 27/30
35/35 [==============================] - 14s 405ms/step - loss: 0.1255 - acc: 0.9723 - val_loss: 0.3385 - val_acc: 0.9727
Epoch 28/30
35/35 [==============================] - 14s 405ms/step - loss: 0.1269 - acc: 0.9598 - val_loss: 0.3627 - val_acc: 0.8594
Epoch 29/30
35/35 [==============================] - 14s 405ms/step - loss: 0.3910 - acc: 0.8741 - val_loss: 0.2908 - val_acc: 0.9453
Epoch 30/30
35/35 [==============================] - 14s 405ms/step - loss: 0.2818 - acc: 0.8848 - val_loss: 0.2633 - val_acc: 0.8945
开始绘图,查看在训练集和测试集上的loss以及acc的变化
history.history.keys()
输出:dict_keys([‘loss’, ‘acc’, ‘val_loss’, ‘val_acc’])
plt.plot(history.epoch,history.history.get("loss"),history.history.get("val_loss"))
plt.plot(history.epoch,history.history.get("acc"),history.history.get("val_acc"))
3、数据的批标准化
1、在传统的机器学习中,标准化也叫归一化,一般是将数据映射到指定的范围,用去除不同维度的数据的量纲以及量纲单位
2、很多特征的取值范围不一样,数据标准化可以让机器学习模型看到的不同样本彼此之间更加相似,这有助于模型的学习与对新数据的泛华
这个模型吃进去的数据都是类似的数据
3、标准化:将数据减去他的平均值使其中心为0,然后将数据除以其标准差使其标准差为1
归一化:取值范围到0-1之间
4、Batch Normalization:批标准化,和普通的数据标准化类似,是将分散的数据统一的一种做法,也是优化神经网络的一种方法,不仅在将数据输入模型之前对数据做标准化,在网络的每一次变换之后都应该考虑数据标准化,即使在训练过程中均值和方法随时间发生变化,他也可以适应性的将数据标准化,每一层看到的数据都是同样的分布
5、批标准化解决的问题就是梯度消失和梯度爆炸,批标准化也是一种训练优化方法
6、数据的预处理做标准化可以加速收敛,在神经网络中使用标准化也可以加速收敛,
具有正则化的效果,能够抑制过拟合
提高模型的泛化能力(无论什么数据过来,都可以处理)
允许更高的学习速率从而加速收敛
批标准化有助于梯度的传播,因此允许更深的网络,对于有些特别深的 网络,只有包含多个Batch Normalization层的时候才能进行训练.
7、Batch Normalization层通常在卷积层或者密集连接层之后使用(实际上放在激活函数之后效果可能会更好)tf.keras.layers.BatchNormalization()
对于上述模型进行改进,再去进行训练
model=tf.keras.Sequential()
model.add(tf.keras.layers.Conv2D(64,(3,3),input_shape=(256,256,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Conv2D(64,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(128,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Conv2D(128,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(256,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.Conv2D(256,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(512,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(512,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.MaxPool2D())
model.add(tf.keras.layers.Conv2D(1024,(3,3)))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dropout(0.5))
model.add(tf.keras.layers.GlobalAveragePooling2D())
model.add(tf.keras.layers.Dense(1024))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dense(256))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dense(10))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation("relu"))
model.add(tf.keras.layers.Dense(1,activation="sigmoid"))
观察网络结构:
Model: "sequential_14"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_61 (Conv2D) (None, 254, 254, 64) 1792
_________________________________________________________________
batch_normalization_24 (Batc (None, 254, 254, 64) 256
_________________________________________________________________
activation_24 (Activation) (None, 254, 254, 64) 0
_________________________________________________________________
dropout_9 (Dropout) (None, 254, 254, 64) 0
_________________________________________________________________
conv2d_62 (Conv2D) (None, 252, 252, 64) 36928
_________________________________________________________________
batch_normalization_25 (Batc (None, 252, 252, 64) 256
_________________________________________________________________
activation_25 (Activation) (None, 252, 252, 64) 0
_________________________________________________________________
dropout_10 (Dropout) (None, 252, 252, 64) 0
_________________________________________________________________
max_pooling2d_33 (MaxPooling (None, 126, 126, 64) 0
_________________________________________________________________
conv2d_63 (Conv2D) (None, 124, 124, 128) 73856
_________________________________________________________________
batch_normalization_26 (Batc (None, 124, 124, 128) 512
_________________________________________________________________
activation_26 (Activation) (None, 124, 124, 128) 0
_________________________________________________________________
dropout_11 (Dropout) (None, 124, 124, 128) 0
_________________________________________________________________
conv2d_64 (Conv2D) (None, 122, 122, 128) 147584
_________________________________________________________________
batch_normalization_27 (Batc (None, 122, 122, 128) 512
_________________________________________________________________
activation_27 (Activation) (None, 122, 122, 128) 0
_________________________________________________________________
dropout_12 (Dropout) (None, 122, 122, 128) 0
_________________________________________________________________
max_pooling2d_34 (MaxPooling (None, 61, 61, 128) 0
_________________________________________________________________
conv2d_65 (Conv2D) (None, 59, 59, 256) 295168
_________________________________________________________________
batch_normalization_28 (Batc (None, 59, 59, 256) 1024
_________________________________________________________________
activation_28 (Activation) (None, 59, 59, 256) 0
_________________________________________________________________
dropout_13 (Dropout) (None, 59, 59, 256) 0
_________________________________________________________________
conv2d_66 (Conv2D) (None, 57, 57, 256) 590080
_________________________________________________________________
batch_normalization_29 (Batc (None, 57, 57, 256) 1024
_________________________________________________________________
activation_29 (Activation) (None, 57, 57, 256) 0
_________________________________________________________________
dropout_14 (Dropout) (None, 57, 57, 256) 0
_________________________________________________________________
max_pooling2d_35 (MaxPooling (None, 28, 28, 256) 0
_________________________________________________________________
conv2d_67 (Conv2D) (None, 26, 26, 512) 1180160
_________________________________________________________________
batch_normalization_30 (Batc (None, 26, 26, 512) 2048
_________________________________________________________________
activation_30 (Activation) (None, 26, 26, 512) 0
_________________________________________________________________
dropout_15 (Dropout) (None, 26, 26, 512) 0
_________________________________________________________________
max_pooling2d_36 (MaxPooling (None, 13, 13, 512) 0
_________________________________________________________________
conv2d_68 (Conv2D) (None, 11, 11, 512) 2359808
_________________________________________________________________
batch_normalization_31 (Batc (None, 11, 11, 512) 2048
_________________________________________________________________
activation_31 (Activation) (None, 11, 11, 512) 0
_________________________________________________________________
dropout_16 (Dropout) (None, 11, 11, 512) 0
_________________________________________________________________
max_pooling2d_37 (MaxPooling (None, 5, 5, 512) 0
_________________________________________________________________
conv2d_69 (Conv2D) (None, 3, 3, 1024) 4719616
_________________________________________________________________
batch_normalization_32 (Batc (None, 3, 3, 1024) 4096
_________________________________________________________________
activation_32 (Activation) (None, 3, 3, 1024) 0
_________________________________________________________________
dropout_17 (Dropout) (None, 3, 3, 1024) 0
_________________________________________________________________
global_average_pooling2d_7 ( (None, 1024) 0
_________________________________________________________________
dense_28 (Dense) (None, 1024) 1049600
_________________________________________________________________
batch_normalization_33 (Batc (None, 1024) 4096
_________________________________________________________________
activation_33 (Activation) (None, 1024) 0
_________________________________________________________________
dense_29 (Dense) (None, 256) 262400
_________________________________________________________________
batch_normalization_34 (Batc (None, 256) 1024
_________________________________________________________________
activation_34 (Activation) (None, 256) 0
_________________________________________________________________
dense_30 (Dense) (None, 10) 2570
_________________________________________________________________
batch_normalization_35 (Batc (None, 10) 40
_________________________________________________________________
activation_35 (Activation) (None, 10) 0
_________________________________________________________________
dense_31 (Dense) (None, 1) 11
=================================================================
Total params: 10,736,509
Trainable params: 10,728,041
Non-trainable params: 8,468
_________________________________________________________________