卷积构造方法
激活函数
在神经网络中,激活函数的作用是能够给神经网络加入一些非线性因素,使得神经网络可以更好地解决较为复杂的问题
在神经网络中,我们有很多的非线性函数来作为激活函数,比如连续的平滑非线性函数(sigmoid,tanh和softplus),连续但不平滑的非线性函数(relu,relu6和relu_x)和随机正则化函数(dropout)
所有的激活函数都是单独应用在每个元素上面的,并且输出张量的维度和输入张量的维度一样
tf.nn.relu(features, name = None):这个函数的作用是计算激活函数relu,即max(features, 0)
tf.nn.relu6(features, name = None):这个函数的作用是计算激活函数relu6,即min(max(features, 0), 6)
tf.nn.softplus(features, name = None):这个函数的作用是计算激活函数softplus,即log( exp( features ) + 1)
tf.sigmoid(x, name = None):这个函数的作用是计算 x 的 sigmoid 函数。具体计算公式为 y = 1 / (1 + exp(-x))
tf.tanh(x, name = None):这个函数的作用是计算 x 的 tanh 函数。具体计算公式为 ( exp(x) - exp(-x) ) / ( exp(x) + exp(-x) )
Dropout 防止过拟合
当训练数据量比较小时,可能会出现因为追求最小差值导致训练出来的模型极度符合训练集,但是缺乏普适性,不能表达训练数据之外的数据
本来有普适性的模型被训练成了具有训练集特殊性
以至于对于真实的数据产生了错误
解决方案:让一部分神经网络不工作 是系数变简单些
tf.nn.dropout(x, keep_prob, noise_shape = None, seed = None, name = None)
卷积层
卷积操作是使用一个二维的卷积核在一个批处理的图片上进行不断扫描。具体操作是将一个卷积核在每张图片上按照一个合适的尺寸在每个通道上面进行扫描
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, name=None)
这个函数的作用是对一个四维的输入数据 input 和四维的卷积核 filter 进行操作,然后对输入数据进行一个二维的卷积操作,最后得到卷积之后的结果
tf.nn.bias_add(value, bias, name = None):这个函数的作用是将偏差项 bias 加到 value 上面
池化层
池化操作是利用一个矩阵窗口在输入张量上进行扫描,并且将每个矩阵窗口中的值通过取最大值,平均值或者XXXX来减少元素个数 相当于降维
Maxpooling 就是在这个区域内选出最能代表边缘的值,然后丢掉那些没多大用的信息
tf.nn.max_pool(value, ksize, strides, padding, name=None):这个函数的作用是计算池化区域中元素的最大值
代码实现
import numpy as np
import tensorflow as tf
# 卷积
input_ = np.random.randn(1,32,32,1)
filter_ = np.random.randn(5,5,1,8) #输出8
conv1 = tf.nn.conv2d(input_,filter_,[1,1,1,1],'VALID')
conv1
#<tf.Tensor 'Conv2D:0' shape=(1, 28, 28, 8) dtype=float64>
# 激活,数据的值改变,形状不变
conv1 = tf.nn.relu(conv1)
conv1
# 池化
pool1 = tf.nn.max_pool(conv1,[1,2,2,1],[1,2,2,1],'SAME')
pool1
#步幅是2 执行完后就变成了14*14 当conv1为25*25时 SAME就会起作用补一个
#<tf.Tensor 'MaxPool:0' shape=(1, 14, 14, 8) dtype=float64>
# 第二层卷积
filter2_ = np.random.randn(5,5,8,20)
conv2 = tf.nn.conv2d(pool1,filter2_,[1,1,1,1],'VALID')
conv2
#<tf.Tensor 'Conv2D_1:0' shape=(1, 10, 10, 20) dtype=float64>
# 第二层池化
pool2 = tf.nn.max_pool(conv2,[1,2,2,1],[1,2,2,1],'SAME')
pool2
#<tf.Tensor 'MaxPool_1:0' shape=(1, 5, 5, 20) dtype=float64>
# 第三层卷积
filter3_ = tf.random_normal(shape = (5,5,20,120),dtype=tf.float64)
conv3 = tf.nn.conv2d(pool2,filter3_,[1,1,1,1],'VALID')
conv3
#tf.Tensor 'Conv2D_3:0' shape=(1, 1, 1, 120) dtype=float64>
# 全连接层
full = tf.reshape(conv3,shape = (1,120))
W = tf.random_normal(shape = [120,9],dtype=tf.float64)
fc = tf.matmul(full,W)
fc
#<tf.Tensor 'MatMul_1:0' shape=(1, 9) dtype=float64>
nd = np.random.randn(30)
nd
#array([-0.12560285, 0.12933899, -1.3299502 , -0.39066039, 0.450362 ,
# 0.09520731, 1.18649637, -0.0540407 , -1.26440829, 0.01215905,
#0.6911983 , 0.09960611, -0.31772857, 1.33419137, -0.44841172,
#-1.08744641, -0.13443044, 1.09703064, -1.31288774, -0.04314629,
#2.30861232, 1.25730727, 0.96198465, -0.81695384, 0.79015532,
#0.70142942, -0.3247638 , -0.0416249 , -0.37326343, 1.11335996])
with tf.Session() as sess:
ret = sess.run(tf.nn.relu(nd))
print(ret) #小于0变为0 大于0不变
#[0. 0.12933899 0. 0. 0.450362 0.09520731
#1.18649637 0. 0. 0.01215905 0.6911983 0.09960611
#0. 1.33419137 0. 0. 0. 1.09703064
#0. 0. 2.30861232 1.25730727 0.96198465 0.
#0.79015532 0.70142942 0. 0. 0. 1.11335996]
#手写激活函数
def relu(nd):
for i,k in enumerate(nd):
if nd[i] < 0:
nd[i] = 0
return nd
relu(nd)
#array([0. , 0.12933899, 0. , 0. , 0.450362 ,
# 0.09520731, 1.18649637, 0. , 0. , 0.01215905,
# 0.6911983 , 0.09960611, 0. , 1.33419137, 0. ,
# 0. , 0. , 1.09703064, 0. , 0. ,
# 2.30861232, 1.25730727, 0.96198465, 0. , 0.79015532,
# 0.70142942, 0. , 0. , 0. , 1.11335996])
卷积神经网络
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('./',one_hot=True)
# 卷积方法
def conv(input_data,filter_,b):
return tf.nn.conv2d(input_data,filter_,[1,1,1,1],'SAME') + b
# 池化:降维
def pool(input_data):
return tf.nn.max_pool(input_data,[1,2,2,1],[1,2,2,1],'SAME')
# 变量可以是filter,bias
def gen_v(shape):
return tf.Variable(initial_value=tf.random_normal(shape = shape,dtype = tf.float64))
第一层卷积
X = tf.placeholder(shape = [None,784],dtype=tf.float64)
y = tf.placeholder(shape = [None,10],dtype=tf.float64)
# 卷积核一般都是小卷积(3,3)、(5,5)
input_data = tf.reshape(X,shape = [-1,28,28,1]) #1维图片
filter1 = gen_v([3,3,1,32]) #1维输入图片 输出为32
b1 = gen_v([32])
conv1 = tf.nn.relu(conv(input_data,filter1,b1)) #进行激活
pool1 = pool(conv1)
pool1
<tf.Tensor 'MaxPool_5:0' shape=(?, 14, 14, 32) dtype=float64>
第二层卷积
filter2 = gen_v([3,3,32,64])
b2 = gen_v([64])
conv2 = tf.nn.relu(conv(pool1,filter2,b2))
pool2 = pool(conv2)
pool2
#<tf.Tensor 'MaxPool_6:0' shape=(?, 7, 7, 64) dtype=float64>
第三层卷积
# filter3 = gen_v([3,3,64,64])
# b3 = gen_v([64])
# conv3 = tf.nn.relu(conv(pool2,filter3,b3))
# pool3 = pool(conv3)
# pool3
#<tf.Tensor 'MaxPool_2:0' shape=(?, 4, 4, 64) dtype=float64>
全连接层 1024个神经元
fc = tf.reshape(pool2,shape = [-1,7*7*64])
fc_w = gen_v([7*7*64,1024])
fc_b = gen_v([1024]) #1024个方程
conn = tf.nn.relu(tf.matmul(fc,fc_w) + fc_b)
conn
#<tf.Tensor 'Relu_8:0' shape=(?, 1024) dtype=float64>
dropout防止过拟合
rate = tf.placeholder(dtype=tf.float64)
dp = tf.nn.dropout(conn,rate =rate) #让一部分不工作 用rate替换
dp
#<tf.Tensor 'dropout_2/mul_1:0' shape=(?, 1024) dtype=float64>
输出层
out_w = gen_v([1024,10])
out_b = gen_v([10])
out = tf.matmul(dp,out_w) + out_b
out
#<tf.Tensor 'add_45:0' shape=(?, 10) dtype=float64>
y_ = tf.nn.softmax(out) #将其转化为概率
y_ = tf.clip_by_value(y_,1e-8,1)
y_
#<tf.Tensor 'clip_by_value_2:0' shape=(?, 10) dtype=float64>
构建损失函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits = out))
loss
#<tf.Tensor 'Mean_19:0' shape=() dtype=float64>
# loss = tf.reduce_mean(tf.reduce_sum(tf.multiply(y,tf.log(1/y_)),axis = 1)) #手写的损失函数
# loss
#<tf.Tensor 'Mean_26:0' shape=() dtype=float64>
优化梯度下降
opt = tf.train.AdamOptimizer(0.001).minimize(loss)
opt #在梯度下降基础上改进
#<tf.Operation 'Adam_17' type=NoOp>
训练
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(10):
for j in range(100):
X_train,y_train = mnist.train.next_batch(550)
opt_,loss_ = sess.run([opt,loss],feed_dict = {X:X_train,y:y_train,rate:0.5}) #训练时吧0.5盖住
print('里层循环执行次数:%d。损失是:%0.4f'%(j+1,loss_))
# 计算准确率
X_validation ,y_validation = mnist.validation.next_batch(2000)
y_pred = sess.run(y_,feed_dict = {X:X_validation,rate:0})
accuracy = (np.argmax(y_pred,axis = -1) == np.argmax(y_validation,axis = -1)).mean()
print('--------------------循环执行%d。准确率是%0.4f-------------------'%(i+1,accuracy))