一、CNN
参考文章https://www.cnblogs.com/kongweisi/p/10987870.html
- 层与层之间的连除了矩阵运算,还有CNN。
- convolution neural network 卷积神经网络
- convolution 卷积是一种数学的运算
- 运算法则:
input image* kernel = feature map
- 行乘以行相加再求和(对应的位置相乘)。
- 每次都是移动一列(这个扫描移动的距离是可以控的)
- kernel(卷积核多大,每次扫描就是多大)
-
卷积扫描后与原数据相比,数据就变少了。
- input layer 数据
- convolvtional layter 1
-
pooling layer 1 池化操作
*池化操作:--数据变少了
- 池化提取大的特征,过滤小的特征。
- 上面图片中的池化的操作,就是四个中选中最大的值,得到数据就行了。
-
池化的大小--一般统一都是2*2操作。
- bias ---偏差
- 相当于方程中的截距
二、卷积神经网络代码实现及作用
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
import tensorflow as tf
(X_train,y_train),(X_test,y_test) = mnist.load_data()
X_train = tf.cast(X_train/255.0,tf.float32)
y_train = tf.one_hot(y_train,depth=10)#10分类问题
X_test = tf.cast(X_test/255,tf.float32)
y_test = tf.one_hot(y_test,depth=10)
# X_train 60000个,重复了100次,每次取512
data_train = tf.data.Dataset.from_tensor_slices((X_train,y_train)).repeat(100).shuffle(2000).batch(512).prefetch(1)
# X_test 10000个,可以取5次,重复50次,250次
data_test = tf.data.Dataset.from_tensor_slices((X_test,y_test)).repeat(50).shuffle(2000).batch(2000).prefetch(1)
repeat(100)重复多少次,shuffle(2000)打乱,batch(512)一批取出的数量,prefetch(1)预先取出数据加快速度。
声明变量
# w系数,卷积核,输入数据是28,28,颜色通道是1,黑白图片
w = {'kernel1':tf.Variable(tf.random.normal(shape = [3,3,1,64],stddev=0.01)),
#tf.random.normal--tf中随机生成数据的方法
'kernel2':tf.Variable(tf.random.normal(shape = [3,3,64,128],stddev=0.01)),#第二层卷积核,以第一层卷积核的结果作为输入
'kernel3':tf.Variable(tf.random.normal(shape = [3,3,128,256],stddev = 0.01)),
'fc':tf.Variable(tf.random.normal(shape = [4*4*256,1024],stddev = 0.01)),
# fc ---定义全连接层
'out':tf.Variable(tf.random.normal(shape = [1024,10],stddev = 0.01))}
# out--输出层
b = {'bias1':tf.Variable(tf.random.normal(shape = [64],stddev=0.01)),
'bias2':tf.Variable(tf.random.normal(shape = [128],stddev=0.01)),
'bias3':tf.Variable(tf.random.normal(shape = [256],stddev=0.01)),
'fc':tf.Variable(tf.random.normal(shape = [1024],stddev=0.01)),
'out':tf.Variable(tf.random.normal(shape = [10],stddev = 0.01))}
# w定义卷积核(filter),定义b,计算结果后加上这个b
# 457万系数,变量!
3*3*64 + 3*3*64*128 +3*3*128*256 + 4*4*256*1024 + 10240
4573760
构造神经网络的模型、损失、准确率、优化算法
def cnn(X):
X = tf.reshape(X,shape = [-1,28,28,1])
# 第一层卷积运算
conv1 = tf.nn.conv2d(input=X,filters=w['kernel1'],strides=[1,1,1,1],padding='SAME') + b['bias1']#卷积
conv1 = tf.nn.max_pool(conv1,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
conv1 = tf.nn.relu(conv1)#激活 conv1.shape = [-1,14,14,64]
# 第二层卷积运算,计算的是,第一层,运算的结果
conv2 = tf.nn.conv2d(input=conv1,filters=w['kernel2'],strides=[1,1,1,1],padding='SAME') + b['bias2']#卷积
conv2 = tf.nn.max_pool(conv2,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
conv2 = tf.nn.relu(conv2)#激活 conv1.shape = [-1,7,7,128]
# 第三层卷积运算,计算的是,第二层,运算的结果
conv3 = tf.nn.conv2d(input=conv2,filters=w['kernel3'],strides=[1,1,1,1],padding='SAME') + b['bias3']#卷积
conv3 = tf.nn.max_pool(conv3,ksize = [1,2,2,1],strides=[1,2,2,1],padding='SAME')#池化
conv3 = tf.nn.relu(conv3)#激活 conv1.shape = [-1,4,4,256] 数据形状是4维
# 全连接层,矩阵操作
fc = tf.reshape(conv3,shape = [-1,4*4*256])
fc = tf.matmul(fc,w['fc']) + b['fc'] #昨天所讲的深度神经网络呢
fc = tf.nn.relu(fc)# 输出的形状 [-1,1024]
# 输出层,真实值,进行对比
y_pred = tf.matmul(fc,w['out']) + b['out']
y_pred = tf.nn.softmax(y_pred)#转变成概率
return y_pred # 输出的形状[-1,10]
# 构建损失,交叉熵
def cross_entropy(y_true,y_pred):
y_pred = tf.clip_by_value(y_pred,1e-9,1.0)
loss = tf.reduce_mean(tf.reduce_sum(tf.multiply(y_true,tf.math.log(1/y_pred)),axis = -1))
return loss
# 构建计算准确率方法
def accuracy(y_true,y_pred):
y_true = tf.argmax(y_true,axis = -1)
y_pred = tf.argmax(y_pred,axis = -1)
acc = tf.reduce_mean(tf.cast(tf.equal(y_true,y_pred),dtype=tf.float16)).numpy()
return acc
# 声明优化算法
sgd = tf.optimizers.Adam(0.001)
全连接层中的每个神经元与其前一层的所有神经元进行全连接.全连接层可以整合卷积层或者池化层中具有类别区分性的局部信息.为了提升 CNN网络性能,全连接层每个神经元的激励函数一般采用ReLU函数。
定义优化方法(定义损失函数)
def run_optimizer(X_train,y_train):
with tf.GradientTape() as g:
y_pred = cnn(X_train)
loss = cross_entropy(y_train,y_pred)
gradients = g.gradient(loss,list(w.values()) + list(b.values()))# 计算梯度,偏导数
sgd.apply_gradients(zip(gradients,list(w.values()) + list(b.values())))
for循环进行训练
for i,(X_train,y_train) in enumerate(data_train.take(100),1):
run_optimizer(X_train,y_train)
if i %10 == 0:
for (X_test,y_test) in data_test.take(1):
y_pred = cnn(X_test)
acc = accuracy(y_test,y_pred)
print('执行次数是:%d。准确率是:%0.4f'%(i,acc))
执行次数是:10。准确率是:0.1190
执行次数是:20。准确率是:0.5630
执行次数是:30。准确率是:0.7002
执行次数是:40。准确率是:0.8047
执行次数是:50。准确率是:0.8711
执行次数是:60。准确率是:0.9004
执行次数是:70。准确率是:0.8755
执行次数是:80。准确率是:0.9199
执行次数是:90。准确率是:0.9238
执行次数是:100。准确率是:0.9380