Tensorflow神经网络框架
以前我们讲了神经网络基础,但是如果从头开始实现,那将是一个庞大且费时的工作,所以我们选择一条捷径———神经网络框架。我理解的神经网络框架就相当于一个工具包。就比如我们去生产一个汽车(神经网络模型),根据自己造的是汽车还是客车(CNN、RNN…),需要我们自己做的就是把不同型号的轮胎、方向盘、发动机(隐藏层、激活函数、梯度下降法)等等、按照一定的图纸(神经网络结构)组装起来。而神经网络框架就相当于放这些轮胎、方向盘、发动机的仓库。在我们需要的时候仓库中取,从而不至于我们在造汽车的时候,再去挖铁矿造钢铁…。因此不同的公司都纷纷的推出了自己的神经网络框架。常见的神经网络有如下几种。
工具名称 | 主要维护人员(或团体) | 支持语音 | 支持系统 |
---|---|---|---|
Caffe | 加州大学伯克利分校视觉与学习中心 | C++、Python、MATLAB | Linux,Mac OS X,Windows |
Deeplearning4j | Skymid | Java,Scala,Clojure | Linux,Windows,Mac Os X,Android |
Mricrosoft Cognitive Tookit(CNTK) | 微软研究院 | Python,C++,BrainSCript | Linux,Windows |
MxNet | 分布式机器学习社区(DMLC) | C++,Python,Julia,MATLAB,GO,R,Scala | Linux,Mac OS X,Windows,Android ,IOS |
paddlepaddle | 百度 | C++, Python | Linux,Mac OS X |
Tensorflow | 谷歌 | C++,Python | Linux,Mac OS X,Androird,ios |
Theano | 蒙特利尔大学 | Python | Linux,Max Os ,Windows |
Torch | Fackbook、Tuitter、Google | Lua、LUaJIT,C | Linux,Mac OS X,Windows,Android,IOS |
PyTorch | Adam Paszke、Sam Gross等 | Python | Linux,Mac OS X |
不同的神经网络有着不同的特点。作为开源的神经网络框架,在选取不同的神经网络框架的时候,时效性占有很大的比重,在GitHub上访问次数最多的就是Tensorflow,而在网络中最活跃的就是Tensorflow,所以我们学习用Tensorflow实现神经网络。
主要顺序就是先写的了神经网络的基本构件,然后构建卷积神经网络和循环神经网络,最后是神经网络的可视化。主要的内容就是解释代码。
例子——>自己三层神经网络——>神经网络可视化——>卷积神经网络——>循环神经网络
通过一个小例子来理解神经网络,下面这个例子为学习一个简单线性模型,下面该例子为通过梯度下降法学习y=0.1x+0.3
- 代码 1
import tensorflow as tf
import numpy as np
#---------------一、创建数据集----------------------
# create data
# x数据集为numpy数据集生成100个0-1之间随机数,定义类型为浮点32位,random为numby中的随机数模块(module),rand()随机生成数组,生成格式为ndarray,astype从新定义数据的类型为32位浮点型。
x_data = np.random.rand(100).astype(np.float32)
y_data = x_data*0.1+0.3
#-------------二、定义神经网络框架--------------
#…………………2.1………………
#creat tensorflow structure start##
# 定义权重,tf.variable()为tf变量类型,初始值为-1到1的维度为1的随机数.
Weights = tf.Variable(tf.random_uniform([1],-1.0,1.0))
# 偏执为维度为1初始值为0的数据
biases = tf.Variable(tf.zeros([1]))
#……………………2.2…………………
#定义训练数据模型
y = Weights*x_data+biases
#……………………2.3……………………
# 定义损失函数(代价函数),代价函数为均方误差函数
loss = tf.reduce_mean(tf.square(y-y_data))
# 优化器为梯度下降法
optimizer = tf.train.GradientDescentOptimizer(0.5)
# 训练过程为通过优化器(优化方法)最小化损失函数。
train = optimizer.minimize(loss)
# 初始化全局变量
init = tf.global_variables_initializer()
#create tensorflow structure end##
#----------三、训练模型-----------
#定义会话,通过会话来运行数据模型
sess = tf.Session()
sess.run(init)
#训练201次
for step in range(201):
sess.run(train)
if step % 20 ==0:
print(step,sess.run(Weights),sess.run(biases))
tensorflow为谷歌开放的神经网络框架,其计算模型为计算图,数据模型为张量,运行模型为会话。
(一)、框架
变量
通过代码理解tensorflow的数据模型
- 代码2
import tensorflow as tf
# @变量练习
# tf变量
state = tf.Variable(0,name='counter')
# tf常量
one = tf.constant(1)
# 定义加法
new_value = tf.add(state , one)
# 更新state,把每次运行的结果返回给state
update = tf.assign(state,new_value)
# 各数据类型
print("type state:",type(state))
print(state)
print("\ntype one:",type(one))
print(one)
print("\ntype new_value",type(new_value))
print(new_value)
print("\ntype update",type(update))
print(update)
# must have if define variable
init = tf.global_variables_initializer()
# 通过会话运行
with tf.Session() as sess:
sess.run(init)
print(sess.run(state))
print(sess.run(one))
print(sess.run(update))
print('-----分割线-----'*5)
with tf.Session() as sess:
sess.run(init)
for _ in range(3):
print(sess.run(update))
print(sess.run(state))
- 结果
type state: <class 'tensorflow.python.ops.variables.Variable'>
<tf.Variable 'counter:0' shape=() dtype=int32_ref>
type one: <class 'tensorflow.python.framework.ops.Tensor'>
Tensor("Const:0", shape=(), dtype=int32)
type new_value <class 'tensorflow.python.framework.ops.Tensor'>
Tensor("Add:0", shape=(), dtype=int32)
type update <class 'tensorflow.python.framework.ops.Tensor'>
Tensor("Assign:0", shape=(), dtype=int32_ref)
0
1
1
-----分割线----------分割线----------分割线----------分割线----------分割线-----
2020-01-21 11:57:01.826930: I C:\tf_jenkins\home\workspace\rel-win\M\windows\PY\36\tensorflow\core\platform\cpu_feature_guard.cc:137] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
1
1
2
2
3
3
Process finished with exit code 0
通过结果可以看出,one,new_value,update的数据模型都为Tensor(张量),这即为tensorflow的数据模型,想要得到其具体的运算过程需要通过会话来运行,如果在定义中有变量,在运行之前需要先初始化所有的变量(init)
会话
神经网络中所有的变量、常量等并不会直接计算,必须要先定义,然后通过会话方式运行。
- 代码 2
# 定义两个矩阵,第一个矩阵为一行两列,第二个矩阵为两行一列。
matrix1 = tf.constant([[3,3]])
matrix2 = tf.constant([[2],
[2]])
# matrix multiply np.dot(m1,m2)
product = tf.matmul(matrix1,matrix2)
# method 1
# sess = tf.Session()
# result = sess.run(product)
# print(result)
# sess.close()
# method 2
with tf.Session() as sess:
result2 = sess.run(product)
print(result2)
(二)、基础知识
placeholder() 和 feed_dict
- placehodlder源码
def placeholder(dtype, shape=None, name=None):
"""Inserts a placeholder for a tensor that will be always fed.
**Important**: This tensor will produce an error if evaluated. Its value must
be fed using the `feed_dict` optional argument to `Session.run()`,
`Tensor.eval()`, or `Operation.run()`.
For example:
'''python
x = tf.placeholder(tf.float32, shape=(1024, 1024))
y = tf.matmul(x, x)
with tf.Session() as sess:
print(sess.run(y)) # ERROR: will fail because x was not fed.
rand_array = np.random.rand(1024, 1024)
print(sess.run(y, feed_dict={x: rand_array})) # Will succeed.
''''
Args:
dtype: The type of elements in the tensor to be fed.
shape: The shape of the tensor to be fed (optional). If the shape is not
specified, you can feed a tensor of any shape.
name: A name for the operation (optional).
Returns:
A `Tensor` that may be used as a handle for feeding a value, but not
evaluated directly.
"""
return gen_array_ops._placeholder(dtype=dtype, shape=shape, name=name)
placeholer为tf中的占位符,这样不需要先定义训练数据,只需要去关心具体的方法,可以先把方法定义好,最后再输入我们的训练数据。通过源码可以看出placeholder必须和feed_dict对应,placeholder为提前定义占位,feed_dict负责最后输入训练数据,必须结合一起使用
- 代码
import tensorflow as tf
#placeholder()
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
output = tf.multiply(input1,input2)
with tf.Session() as sess:
print(sess.run(output,feed_dict={
input1:[7.],input2:[2.]}))
通过placeholder定义加法运算
激活函数
激活函数,当一个线性模型向非线性模型转换过程中,需要非线性变换,这种变换通过为仿射变换结合激活函数(激活函数具体内容详见第一部分神经网络基础知识)
python内置的激活函数如下:
@@relu
@@relu6
@@crelu
@@elu
@@leaky_relu
@@selu
@@softplus
@@softsign
@@dropout
@@bias_add
@@sigmoid
@@log_sigmoid
@@tanh
@@convolution
@@conv2d
@@depthwise_conv2d
@@depthwise_conv2d_native
@@separable_conv2d
@@atrous_conv2d
@@atrous_conv2d_transpose
@@conv2d_transpose
@@conv1d
@@conv3d
@@conv3d_transpose
@@conv2d_backprop_filter
@@conv2d_backprop_input
@@conv3d_backprop_filter_v2
@@depthwise_conv2d_native_backprop_filter
@@depthwise_conv2d_native_backprop_input
@@avg_pool
@@max_pool
@@max_pool_with_argmax
@@avg_pool3d
@@max_pool3d
@@fractional_avg_pool
@@fractional_max_pool
@@pool
@@dilation2d
@@erosion2d
@@with_space_to_batch
@@l2_normalize
@@local_response_normalization
@@sufficient_statistics
@@normalize_moments
@@moments
@@weighted_moments
@@fused_batch_norm
@@batch_normalization
@@batch_norm_with_global_normalization
@@l2_loss
@@log_poisson_loss
@@sigmoid_cross_entropy_with_logits
@@softmax
@@log_softmax
@@softmax_cross_entropy_with_logits
@@sparse_softmax_cross_entropy_with_logits
@@weighted_cross_entropy_with_logits
@@embedding_lookup
@@embedding_lookup_sparse
@@dynamic_rnn
@@bidirectional_dynamic_rnn
@@raw_rnn
@@static_rnn
@@static_state_saving_rnn
@@static_bidirectional_rnn
@@ctc_loss
@@ctc_greedy_decoder
@@ctc_beam_search_decoder
@@top_k
@@in_top_k
@@nce_loss
@@sampled_softmax_loss
@@uniform_candidate_sampler
@@log_uniform_candidate_sampler
@@learned_unigram_candidate_sampler
@@fixed_unigram_candidate_sampler
@@compute_accidental_hits
@@quantized_conv2d
@@quantized_relu_x
@@quantized_max_pool
@@q
其中常用的激活函数有,relu、sigmoid、softplus、than等
(三)、神经网络方法
1、首先自己构造一个简单的三层神经网络方法
代码3.1
import tensorflow as tf
import numpy as np
# -----------------------1--------------------------------
# 定义添加层函数
def add_layer(inputs,in_size,out_size,activation_function=None):
# 权重变量矩阵
Weight = tf.Variable(tf.random_normal([in_size,out_size]),name='W')
# 偏执初始值建议不为0
biases = tf.Variable(tf.zeros([1,out_size])+0.1,name='b')
Wx_plus_b = tf.matmul(inputs,Weight)+biases
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b)
return outputs
#------------------------2------------------------------------
#创建训练集
x_data = np.linspace(-1,1,300)[:,np.newaxis]
# 噪音均值为0方差为0.05
noise = np.random.normal(0,0.05,x_data.shape)
y_data = np.square(x_data)-0.5+noise
#-----------------------3----------------------------------------
#定义输入层,有几个输入数据,就需要定义几个单元
xs = tf.placeholder(tf.float32,[None,1],name='x_input')
ys = tf.placeholder(tf.float32,[None,1],name='y_input')
#定义隐藏层,隐藏层为10个单元
l1 = add_layer(xs,1,10,activation_function=tf.nn.relu)
#定义输出层
predition = add_layer(l1,10,1,activation_function=None)
#-----------------------4-----------------------------------------
#损失函数
loss = tf.reduce_mean(tf.reduce_sum(tf.square(ys-predition),reduction_indices=[1]))
#-----------------------5------------------------------------------
#训练梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(loss)#学习率为0.1,小于1即可
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
for i in range(1000):
sess.run(train_step,feed_dict={
xs:x_data,ys:y_data})
if i%50 == 0:
print(sess.run(loss,feed_dict={
xs:x_data,ys:y_data}))
- 输出
0.15612674
0.01370755
0.011248722
0.009909462
0.008916998
0.00815641
0.007569391
0.0069189603
0.00624108
0.0056113983
0.005094583
0.004754079
0.004478738
0.004224704
0.004011159
0.0038203541
0.0036806199
0.0035679673
0.0034924054
0.0034372727
第一部分为定义一个添加层函数,第二部分利用numpy手动创建一个训练集,第三部分定义层,分别为输入层,隐藏层,输出层,第四部分为定义一个代价函数,代价函数为最小均方误差函数,第五部分为利用梯度下降法最小化代价函数训练模型,通过输出值可以看到误差逐渐减小,这既是一个模型学习的过程。
- 代码3.2 可视化(1)
在上述代码的基础上通过matplotlib进行可视化过程
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
# -----------------------1--------------------------------
# 定义添加层函数
def add_layer(inputs,in_size,out_size,activation_function=None):
# 权重变量矩阵
Weight = tf.Variable(tf.random_normal([in_size,out_size]),name='