简介
TensorFlow是采用数据流图,用于数值计算的深度学习框架(常用于神经网络相),其中在数据流图里,节点表示数学操作,线表示节点间相互联系的数据,即张量(tensor)
安装
其分为CPU和GPU(更快,但要有硬件支持)版本,安装命令如下:
pip install tensorflow
pip install tensorflow-gpu
注:
安装时要求python版本为2.7+或者3.5+(3.5需要为64位)
使用步骤
Tensorflow不单独地运行单一的复杂计算,而是让我们可以先用图描述一系列可交互的计算操作,然后全部一起在Python之外运行,从而减少开销,因此基本上所有的 Tensorflow 代码都包含两个重要部分:
1.计算图(Graph),表示计算任务
2.会话(Session),用于执行计算图中的运算
因此使用步骤大体如下:
1.导入tensorflow框架:import tensorflow as tf
2.创建计算图,定义张量(如:常量tf.constant()
、变量tf.Variable()
等)和运算方法(如:矩阵乘法tf.matmul()
等)
3.创建会话(sess = tf.session()
),用于运行计算图中运算
4.通过会话运行计算(sess.run()
)
5.关闭会话(sess.close()
)
简单示例
import tensorflow as tf
x = tf.constant([[1,2]])
# 创建一个1行2列的矩阵
y = tf.constant([[3], [4]])
# 创建一个两行一列的矩阵
mul = tf.matmul(x, y)
# 将两个矩阵相乘
sess = tf.Session()
# 创建一个会话
result = sess.run(mul)
# 执行前面运算图中定义的常量和运算方法
print(result)
# 输出运算图中乘法运算执行的结果
sess.close()
# 关闭会话
由于会话执行结束后需要关闭,因此上面的也可以使用with
关键字来实现自动关闭,举例:
import tensorflow as tf
with tf.Session() as sess:
# 使用with关键字可以在sess使用结束时自动关闭资源
x = tf.constant([[1, 2]])
y = tf.constant([[3], [4]])
mul = tf.matmul(x, y)
result = sess.run(mul)
print(result)
基本语句
定义常量
tf.constant()
注:
当运算图中定义了变量以后,需要在会话中先调用语句tf.global_variables_initializer()
来对所有变量进行初始化
定义变量
tf.Variable()
数据类型转换
tf.cast(x, xtype)
,可以将前面的数据类型进行转换,举例:
x = tf.Variable([1,2,3,4,5])
y = tf.cast(x,dtype=tf.float32)
基本运算
加减乘除
tf.add(x, y)
/subtract(x, y)
/tf.multiply(x, y)
/tf.div(x, y)
(整除)/tf.divide(x, y)
(小数除,需要除数被除数都为float),举例:
import tensorflow as tf
init = tf.Variable(10.0)
# 定义一个变量
two = tf.constant(2.0)
# 定义一个常量
div_two = tf.divide(init, two)
# 定义一个除法运算
矩阵相乘
tf.matmul(x, y)
平方运算
tf.square(x)
获取矩阵里数的总和/平均值/最大值/最小值
tf.reduce_sum(x)
/reduce_mean(x)
/reduce_max(x)
/reduce_min(x)
生成几行几列的随机数矩阵
tf.random_uniform([m], x, y)
,即生成格式为m
,数值全为x
到y
的随机数矩阵
生成几行几列的全零矩阵
tf.zeros([m])
,生成格式为m
的全零矩阵
判断是否相等
tf.equal(x, y)
,判断x、y的值是否相等,返回bool类型
更新(赋值)变量
tf.assign(x, way)
,将x
以way
方式更新数据,即赋值操作
使用举例:
import tensorflow as tf
init = tf.Variable(0)
# 定义一个变量
one = tf.constant(1)
# 定义一个常量
add_one = tf.add(init, one)
# 定义一个加法运算
update = tf.assign(init, add_one)
# 定义一个将当前值加一并更新的运算
init_var = tf.global_variables_initializer()
# 定义一个变量初始化
with tf.Session() as sess:
sess.run(init_var)
# 初始化变量
for i in range(3):
print(sess.run(update), end="\t")
# 输出每次加1并更新后的结果
# 结果为:
# 1 2 3
返回最大值索引
tf.argmax(input,axis)
,返回输入内容的最大值索引,当axis
为0时代表一维,根据每一列返回最大索引,axis
为1时代表二维,根据每一行返回最大索引,以此类推
详细参考:
https://blog.csdn.net/u012300744/article/details/81240580
传值/返回值
feed_dict传参
对于会话中的run()
方法,一般都是将常量和初始化完成的变量传入运算,但其实也可以通过feed_dict
参数将数值以字典方式传入,此时对于这些值,需要先通过tf.placeholder()
方法创建占位符,然后再传入对应格式的数据,举例:
import tensorflow as tf
input1 = tf.placeholder(tf.float32)
input2 = tf.placeholder(tf.float32)
# 创建两个float型占位符
output = tf.multiply(input1, input2)
# 进行乘法运算
with tf.Session() as sess:
print(sess.run([output], feed_dict={input1:7., input2:2.}))
# 传入两个占位符的值分别为7.0和2.0
占位符
tf.placeholder(xtype[, shape, name=xx])
占位符的传参依次分别是:传入类型、传入格式和命名(name
),由于命名为名称参数,主要在可视化当中使用,这里不说。这里介绍下传入类型和传入格式
- 传入类型
tf.float32 -> float(最常用)
tf.float64 -> double
tf.double -> double(和上面那个一样的)
tf.int32 -> int
tf.uint32 -> int(正数部分)
...
从源代码当中也可以看到传入类型的定义:
np.bool_: (False, True),
np.bool8: (False, True),
np.uint8: (0, 255),
np.uint16: (0, 65535),
np.int8: (-128, 127),
np.int16: (-32768, 32767),
np.int64: (-2**63, 2**63 - 1),
np.uint64: (0, 2**64 - 1),
np.int32: (-2**31, 2**31 - 1),
np.uint32: (0, 2**32 - 1),
np.float32: (-1, 1),
np.float64: (-1, 1)
- 传入格式
传入格式需要说明的不多,就是就是定义几行几列、比如2行1列就是:[2, 1]
,如果多维度,就几维几行几列那样以此类推,可以参考np.array()
的shape
,要注意的是None
,这个代表任意的意思,比如任意行1列就是:[None, 1]
举例:
tf.placeholder(tf.float32, [None, 1])
# 定义数据为浮点数,任意行,1列的占位符
Fetch返回值
执行会话操作时的sess.run()
语句时,将会返回对应输入参数的结果值
其他方法
tf.pad
扩展矩阵,分别从各个维度方向扩展数据,参考:
https://blog.csdn.net/qq_40994943/article/details/85331327
https://blog.csdn.net/luoganttcc/article/details/83303522
激活函数
激活函数作用简单来说就是原来的中间层只是单纯的矩阵相乘,因此只能解决线性问题,使用激活函数以后,就能解决线性相关问题了,具体参考:
https://blog.csdn.net/program_developer/article/details/78704224
tanh
tf.nn.tanh
,数据随tanh
函数的曲线变化
relu
tf.nn.relu
,其将所有小于0的数置为0,大于0的数保持不变
参考:https://blog.csdn.net/Random_R/article/details/80523265
sigmoid
tf.nn.sigmoid
,数据随1/(1+e^-x)
函数曲线变化
softmax
tf.nn.softmax
参考:https://blog.csdn.net/red_stone1/article/details/80687921
损失函数/交叉熵函数
学习训练模型时,需要有一个参照值作为训练的标准,比如设置一个损失函数,其值为预测值和正确值之差的平方和取平均值,代码如下:
loss = tf.reduce_mean(tf.square(y-prediction))
损失函数的变化梯度和激活函数的梯度相关,而交叉熵的变化梯度则和预测值和正确值之间的误差有关,当误差越大时,梯度越大,反之越小,因此线性预测时,适合用损失函数,非线性的适合用交叉熵,其中交叉熵一般和sigmoid()
/softmax()
结合使用(tf.nn.softmax_cross_entropy_with_logits()
/tf.nn.sigmoid_cross_entropy_with_logits()
),交叉熵使用举例:
loss = tf.nn.softmax_cross_entropy_with_logits(labels=y, logits=prediction)
# labels传入正确值,logits传入预测值
注:
使用上面的交叉熵函数时,里面包括了sigmoid()
/softmax()
方法,因此不需要再调用这些激活函数
优化器
tf.train()
,其下提供了很多优化器,其中最简单的就是梯度下降GradientDescentOptimizer()
,里面需要传入学习率(优化器的用法基本都差不多),举例:
optimizer = tf.train.GradientDescentOptimizer(0.01)
# 基于梯度下降法,学习率为0.01的优化器
优化器的作用就是设置一个参照值,在设置一个目标,比如越小越好,以此为根据从而不断训练,例如以前面的损失函数为标准,目标是越低越好,举例:
train = optimizer.minimize(loss)
AdamOptimizer()
这个是比较好的优化器,较为推荐
各种优化器详解
https://blog.csdn.net/weixin_40170902/article/details/80092628
学习率问题
使用优化器时,设置学习率是个很重要的问题,学习率设置过大,则可能无法拟合数据,设置过小,则可能拟合过慢,并且随着迭代次数的增加,拟合的变化量将越来越小,此时如果学习率不够小,也将无法继续拟合,因此可以在设置起始学习率时,调一个差不多的值,并随着迭代次数减小学习率,从而达到能够较快速且不断拟合的效果
拟合问题
对于模型训练,如果提供的数据量过少,则可能出现过拟合问题,此时解决方案一般有以下几种:
1.增加数据量
2.数据正则化
3.dropout随机选取
dropout()
一次随机选取一定比例的神经元,举例:
tf.nn.dropout(x, 0.5)
# 在x中选取一半的数据
会话操作
创建会话
sess = tf.Session()
执行运算
sess.run()
注:
如果只传入一个运算,那么当前会话会返回该运算执行完毕后对应的结果,但如果想进行多个运算并返回多个对应的结果,则可以通过一个列表将多个运算一起传入,结果也是一个列表,依次为每个运算的结果
注2:
当传入多个运算时,其将一起执行,而不是按传入顺序去执行,因此如果在一次run()
里传入多个相同的运算,那么就相当于执行一次
关闭会话
sess.close()
模型保存和载入
保存模型
在会话操作前通过saver = tf.train.Saver()
定义一个保存器,当模型训练完毕时,通过saver.save(sess, '路径')
来保存模型,举例:
# 定义操作
...
saver = tf.train.Saver()
with tf.Session() as sess:
# 模型训练操作
...
saver.save(sess, 'test_model.ckpt')
# 训练完成,保存模型
载入模型
通过saver.restore(sess, '路径')
来载入模型,举例:
...
saver = tf.train.Saver()
with tf.Session() as sess:
saver.restore(sess, 'test_model.ckpt')
# 载入模型到sess
# 可以直接使用模型进行操作了
...
简单综合示例
import tensorflow as tf
# 预测一个一元线性方程y=Wx+b的W和b的值,使其符合当x依次为1,2,3,4时,对应的y值依次为0,-1,-2,-3
W = tf.Variable(1., tf.float32)
b = tf.Variable(-1., tf.float32)
# 定义变量W和b,值分别为1.0和-1.0
x = tf.placeholder(tf.float32)
y = tf.placeholder(tf.float32)
# 定义占位符,用于执行开始时的数据输入
init = tf.global_variables_initializer()
# 定义初始化变量
linear_model = W*x + b
# 定义y=Wx+b的一元线性方程模型
squared_deltas = tf.square(linear_model - y)
# 定义期望值和实际值之差的平方,用于后面的损失函数
loss = tf.reduce_sum(squared_deltas)
# 定义损失函数,值为所有计算差的平方和
optimizer = tf.train.GradientDescentOptimizer(0.01)
# 定义一个梯度下降的优化器,学习速率为0.01
train = optimizer.minimize(loss)
# 通过梯度下降方法尽可能使损失函数的值减小
with tf.Session() as sess:
sess.run(init)
# 初始化变量
for i in range(1000):
sess.run(train, {x: [1., 2., 3., 4.], y: [0., -1., -2., -3.]})
# 训练1000次,并在这期间自动调整W和b的大小
print(sess.run([W, b]))
# 输出训练1000次后W和b的值:[-0.99999523, 0.999986](最完美的是W=-1,b=1,但不可能达到)
示例2
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
# 生成-0.5到0.5的200个等差数列,并转成二维数据,即从1行200列转成200行1列
noise = np.random.normal(0, 0.02, x_data.shape)
# 生成和x_data格式相同的噪音数据
y_data = np.square(x_data) + noise
# 期望值为x_data的平方加上噪音
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
# 定义两个占位符,要求格式为:任意行,1列的数据
# 定义中间层
W1 = tf.Variable(tf.random_normal([1, 10]))
# 定义1行10列的随机矩阵权重,即中间层有10个神经元
b1 = tf.Variable(tf.zeros([1, 10]))
# 定义偏差
y_Wb1 = tf.matmul(x, W1) + b1
# 中间层对输入数据进行计算:输入数据与权重相乘后加上偏差值
lay1 = tf.nn.tanh(y_Wb1)
# 通过tanh激活函数来传达到下一层
# 定义输出层
W2 = tf.Variable(tf.random_normal([10, 1]))
# 经过中间层,输出结果由1行1列转成了1行10列,因此定义10行1列随机矩阵权重进行接收
b2 = tf.Variable(tf.zeros([1, 1]))
# 定义偏差
y_Wb2 = tf.matmul(lay1, W2) + b2
# 计算输出结果
output = tf.nn.tanh(y_Wb2)
# 激活函数输出
loss = tf.reduce_mean(tf.square(y - output))
# 损失函数值为输出结果与期望结果之差平方的平均值
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
# 定义梯度下降优化器,学习率为0.1,尽量让损失值小
init = tf.global_variables_initializer()
# 注意初始化要写在所有变量定义结束后
with tf.Session() as sess:
sess.run(init)
# 初始化变量
fig = plt.figure()
plt.ion()
# 动态交互式图形
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
# 绘画散点数据
for i in range(2000):
sess.run(train_step, feed_dict={x:x_data, y:y_data})
# 训练2000次
if i % 100 == 0:
prediction = sess.run(output, feed_dict={x:x_data})
# 每训练100次的预测曲线
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
# 删除原先折线
except Exception as e:
pass
lines = ax.plot(x_data, prediction, 'red', lw=5)
# 绘画预测数据折线
plt.ioff()
# 关闭交互
plt.show()
上面的代码结合神经网络层的原理,还可以换成下面那样表示:
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
def add_layer(input, input_size, output_size, activation=None):
'''定义神经网络层'''
W = tf.Variable(tf.random.normal([input_size, output_size]))
b = tf.Variable(tf.zeros([1, output_size]))
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
x_data = np.linspace(-0.5, 0.5, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.02, x_data.shape)
y_data = np.square(x_data) + noise
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
layer1 = add_layer(x, 1, 10, tf.nn.tanh)
# 进入隐藏层
output = add_layer(layer1, 10, 1, tf.nn.tanh)
# 输出层
loss = tf.reduce_mean(tf.square(y-output))
train = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
plt.ion()
plt.scatter(x_data, y_data)
for i in range(2000):
sess.run(train, feed_dict={x: x_data, y: y_data})
if i % 50 == 0:
result = sess.run(output, feed_dict={x: x_data})
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
except:
pass
lines = ax.plot(x_data, result, 'red')
plt.ioff()
plt.show()
小小拓展:
如果把一开始初始化的数据改大点(比如:-5~5),观察下运行情况可以发现上面的代码就完全不拟合了,其原因如下:
1.由于输出层使用了tanh()
激活函数,最终的结果被压缩到了-1~1之间,因此无法进行拟合,此时只要把输出层的激活函数给去掉就行了。
如果依旧拟合不是很好,那么可以再参考以下优化方法:
1.增加初始化数据集的量
2.增加神经层数和神经元的数量
3.修改损失函数
4.修改优化器或优化器的学习率
...
比如修改成-5~5之间可以把代码修改如下:
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
x_data = np.linspace(-5, 5, 2000)[:, np.newaxis]
# 数据量增加到2000
noise = np.random.normal(0, 0.02, x_data.shape)
y_data = np.square(x_data) + noise
x = tf.placeholder(tf.float32, [None, 1])
y = tf.placeholder(tf.float32, [None, 1])
W1 = tf.Variable(tf.random_normal([1, 10]))
b1 = tf.Variable(tf.zeros([1, 10]))
y_Wb1 = tf.matmul(x, W1) + b1
lay1 = tf.nn.tanh(y_Wb1)
W2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]))
y_Wb2 = tf.matmul(lay1, W2) + b2
output = y_Wb2
# 取消输出层的激活函数
loss = tf.reduce_mean(tf.square(y - output))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
# 降低学习率
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
fig = plt.figure()
plt.ion()
ax = fig.add_subplot(1,1,1)
ax.scatter(x_data, y_data)
for i in range(2000):
sess.run(train_step, feed_dict={x:x_data, y:y_data})
if i % 100 == 0:
prediction = sess.run(output, feed_dict={x:x_data})
plt.pause(0.1)
try:
ax.lines.remove(lines[0])
except Exception as e:
pass
lines = ax.plot(x_data, prediction, 'red', lw=5)
plt.ioff()
plt.show()
卷积神经网络CNN
传统神经网络问题:权值多,计算量大,需要大量样本进行训练,卷积神经网络则是分块处理,取特征值,一般包括卷积层和池化层,常用于图像处理等
卷积层
通过tf.nn.conv2d(input, filter, strides, padding)
实现,传入参数说明:
1.input
:输入数据,是一个列表:[batch, in_height, in_width, in_channels],分别代表数据量,数据高宽,以及通道数(黑白则为1,彩色包括红绿蓝则为3)
2.filter
:滤波器,即每次分块处理的参数,是一个列表:[filter_height, filter_width, in_channels, out_channels],分别代表滤波器高宽,以及输入输出通道数
3.strides
:步长,也是个列表:[1, x, y, 1],第一个和最后一个参数为1,中间两个代表x,y方向的步长
4.padding
:卷积操作(特征抽取),有same
和valid
两种方法,第一种代表当分块时整体内容不够凑一块,则周围用0补全,然后再取特征值,第二种则直接放弃特征值抽取
池化层
通过tf.nn.max_pool(input, ksize, strides, padding)
实现,传入参数说明:
1.input
:输入数据
2.ksize
:池化窗口大小,是一个列表:[1, height, width, 1],第一个和第四个必须为1,中间两个为尺寸
3.strides
:步长
4.padding
:卷积操作,有same
和valid
两种方法
循环神经网络RNN
循环神经网络,里面存在隐层,能够将前一个的分析结果往后传递,类似反向传播,但因为RNN中信号向下传播时会逐渐减弱,因此需要有能够选择性记住靠谱信号,过滤不靠谱信号的模型,即LSTM(Long Short TermMemory)
RNN实现
1.通过tf.contrib.rnn.core_rnn_cell.BasicLSTMCell()
设置LSTM单元数
2.通过tf.nn.dynamic_rnn(lstm_cell, input, dtype)
实现RNN,分别传入三个参数:LTMS单元、输入数据以及格式,返回的值有输出结果和final_state
,其中final_state
是一个列表,第一个值为0代表cell_state
,为1代表hidden_state
,第二个是批次样本数batch_size
,举例:
def RNN(X,weights,biases):
inputs = tf.reshape(X,[-1,max_time,n_inputs])
lstm_cell = tf.contrib.rnn.core_rnn_cell.BasicLSTMCell(lstm_size)
outputs,final_state = tf.nn.dynamic_rnn(lstm_cell,inputs,dtype=tf.float32)
results = tf.nn.softmax(tf.matmul(final_state[1],weights) + biases)
return results
可视化框架tensorboard
使用步骤
1.首先需要给各个部分通过tf.name_scope
设置命名空间
2.分别对命名空间下的数据设置name
属性,否则会自动设置默认属性
3.在会话当中通过tf.summary.FileWriter('文件生成路径', sess.graph)
生成图像
4.在文件生成路径的父文件夹中打开命令行输入命令:tensorboard --logdir=路径 --host 127.0.0.1
,进入网址找到graph即可,举例:
tensorboard --logdir=logs --host 127.0.0.1
代码示例
import numpy as np
import tensorflow as tf
def add_layer(input, input_size, output_size, activation=None):
'''定义神经网络层'''
with tf.name_scope('Weight'):
W = tf.Variable(tf.random.normal([input_size, output_size]), name='W')
with tf.name_scope('biases'):
b = tf.Variable(tf.random.normal([1, output_size]), name='b')
with tf.name_scope('Y_Wb'):
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
lr = 0.001
x_data = np.linspace(-1, 1, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.1, x_data.shape)
y_data = np.square(x_data) + noise
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None, 1], name='x')
y = tf.placeholder(tf.float32, [None, 1], name='y')
with tf.name_scope('layer1'):
layer1 = add_layer(x, 1, 3, tf.nn.relu)
with tf.name_scope('layer2'):
layer2 = add_layer(layer1, 3, 5, tf.nn.relu)
with tf.name_scope('layer3'):
prediction = add_layer(layer2, 5, 1, tf.nn.relu)
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
with tf.name_scope('train'):
train = tf.train.AdamOptimizer(lr).minimize(loss)
init = tf.global_variables_initializer()
# 不用设置init,默认会自动创建
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/', sess.graph)
for i in range(2000):
sess.run(train, feed_dict={x: x_data, y: y_data})
lr *= 0.99
if i % 50 == 0:
result = sess.run(prediction, feed_dict={x: x_data})
print(sess.run(loss, feed_dict={x: x_data, y: y_data}))
# 在生成文件目录的上一层打开命令行输入以下命令:
# tensorboard --logdir=logs --host 127.0.0.1
# 进入提供的网址即可
注:
使用中出现问题:oserror: [errno 22] invalid argument
参考:https://blog.csdn.net/u013244846/article/details/88380860
数据记录展示
如果希望展示某些数据的走向趋势的话,可以通过tf.summary.scalar()
来对数据进行曲线展示,tf.summary.histogram()
进行直方图展示,然后再会话当中通过tf.summary.merge_all()
合并所有展示内容,最后通过writer.add_summary()
将内容写至生成文件当中,举例:
import numpy as np
import tensorflow as tf
def add_layer(input, input_size, output_size, activation=None):
with tf.name_scope('Weight'):
W = tf.Variable(tf.random.normal([input_size, output_size]), name='W')
with tf.name_scope('biases'):
b = tf.Variable(tf.random.normal([1, output_size]), name='b')
with tf.name_scope('Y_Wb'):
layer = tf.matmul(input, W) + b
if activation:
layer = activation(layer)
return layer
lr = 0.001
x_data = np.linspace(-1, 1, 200)[:, np.newaxis]
noise = np.random.normal(0, 0.1, x_data.shape)
y_data = np.square(x_data) + noise
with tf.name_scope('input'):
x = tf.placeholder(tf.float32, [None, 1], name='x')
y = tf.placeholder(tf.float32, [None, 1], name='y')
with tf.name_scope('layer1'):
layer1 = add_layer(x, 1, 3, tf.nn.relu)
with tf.name_scope('layer2'):
layer2 = add_layer(layer1, 3, 5, tf.nn.relu)
with tf.name_scope('layer3'):
prediction = add_layer(layer2, 5, 1, tf.nn.relu)
with tf.name_scope('loss'):
loss = tf.reduce_mean(tf.square(y-prediction))
with tf.name_scope('summary'):
tf.summary.scalar('mean', tf.reduce_mean(loss))
tf.summary.scalar('max', tf.reduce_max(loss))
tf.summary.scalar('min', tf.reduce_min(loss))
tf.summary.histogram('loss', loss)
# 展示损失函数的平均、最大、最小值变化,以及自身值的直方图
with tf.name_scope('train'):
train = tf.train.AdamOptimizer(lr).minimize(loss)
init = tf.global_variables_initializer()
merged = tf.summary.merge_all()
# 合并所有展示内容
with tf.Session() as sess:
sess.run(init)
writer = tf.summary.FileWriter('logs/', sess.graph)
for i in range(2000):
_, summary = sess.run([train, merged], feed_dict={x: x_data, y: y_data})
writer.add_summary(summary, i)
# 数据图表添加到文件当中
lr *= 0.99
if i % 50 == 0:
result = sess.run(prediction, feed_dict={x: x_data})
print(sess.run(loss, feed_dict={x: x_data, y: y_data}))
莫凡TensorFlow教程
https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/1-1-A-ANN-and-NN/