以下是自己学习莫烦Python中的笔记
import tensorflow as tf
import numpy as np
def add_layer(inputs, in_size, out_size, activation_function=None): # activation_function=None表示默认线性函数
Weights = tf.Variable(tf.random_normal([in_size, out_size])) # 设置权重矩阵,in_size行,out_size列的矩阵,推荐用随机变量,比全0好
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) # 定义偏置项
Wx_plus_b = tf.matmul(inputs, Weights) + biases # 未被激活
if activation_function is None: # 线性的不需要激活函数
output = Wx_plus_b
else:
output = activation_function(Wx_plus_b) # 需要激活函数
return output
'''构建数据'''
x_data = np.linspace(-1, 1, 300)[:, np.newaxis] # newaxis = None,添加维度,变成矩阵的形式
noise = np.random.normal(0, 0.05, x_data.shape) # 添加噪点,让它不完全拟合原来的函数
y_data = np.square(x_data) + 0.5 + noise # 定义的y
'''定义一个输入层(1个神经元),隐藏层(10个神经元),输出层(1个神经元)的简单神经网络'''
'''xs,ys存在的意义是可配置,不把程序写死,解耦,这样可以改变模型的输入值,直接传不方便封装,模型就只能对x_data,y_data进行预测'''
xs = tf.placeholder(tf.float32, (None, 1)) # 输给train_step的值,xs,ys,这里的None后面就是batch_size,None表示随意什么值
ys = tf.placeholder(tf.float32, (None, 1)) # placeholder的作用是用来穿数据的,1是x_data,y_data的属性是1
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# 定义layer 1,调用添加层函数,传入数据:输入数据,输如神经元个数,输出神经元个数(从第一层进入隐藏层,一个进去,10个出来)
# 定义激活函数relu,相当于用10条直线去拟合一个抛物线
prediction = add_layer(l1, 10, 1, activation_function=None)
# 定义输出层,也就是预测曾,传入从隐藏层输出的10个神经元,传出prediction层输出的1个神经元,激活函数默认线性
'''定义损失函数'''
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data-prediction), # 真实值减去预测数据的平方求和再平均
reduction_indices=[1])) # reduction_indices=[1]表示结果压缩的方向,1表示列方向压缩
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
# 采用梯度下降的优化算法以0.1的学习率(优化的步长取值)每训练一次,对误差进行更正或提升,下次会有更好的结果
'''所有变量初始化,并启用会话设置'''
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
for i in range(10000): # train_step10000次
# 这里我们可以采用小步骤执行,一次不处理全部的数据,可以解决并行数据量大
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 100 == 0:
print(sess.run(loss, feed_dict={xs: x_data, ys: y_data}))
'''
运行结果:
0.5493656
0.0107342955
0.0070284773
0.006592798
0.0063318294
0.006061059
0.005771474
0.005488769
0.005196031
0.0044501587
0.0042058867
0.004073246
0.003959596
0.0038633016
0.0037791408
0.0036934523
0.0036113774
0.0035319463
0.003464909
0.0034044054
0.0033475696
0.0032985774
0.0032570336
0.0032204872
0.0031877018
0.0031564569
0.0031279041
0.003102748
0.0030788844
0.0030579553
0.0030362464
0.0030177354
0.0030016755
0.002987475
0.0029756082
0.0029649814
0.0029550295
0.0029448003
0.0029357218
0.0029277373
0.0029169486
0.0029066761
0.0028959094
0.0028867824
0.0028785528
0.002870171
0.0028620618
0.0028546161
0.002847477
0.0028404433
0.002833517
0.0028268904
0.0028205125
0.0028145504
0.002808905
0.0028017273
0.0027929782
0.0027851863
0.0027749557
0.0027644003
0.0027537593
0.0027437778
0.0027352145
0.0027273197
0.0027202086
0.0027134544
0.0027047154
0.0026974839
0.002690782
0.0026839096
0.0026774737
0.0026713694
0.0026650357
0.0026573725
0.0026495687
0.0026424658
0.0026353367
0.0026287038
0.002622738
0.0026163943
0.002610145
0.002604464
0.002599055
0.0025937355
0.0025889135
0.0025844388
0.0025796301
0.0025742496
0.0025692824
0.002564779
0.0025596002
0.0025547268
0.0025502879
0.002546214
0.0025425574
0.0025390468
0.0025354468
0.0025319364
0.002528599
0.002525389
'''
'''结果可视化'''
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
def add_layer(inputs, in_size, out_size, activation_function=None): # activation_function=None表示默认线性函数
Weights = tf.Variable(tf.random_normal([in_size, out_size])) # 设置权重矩阵,in_size行,out_size列的矩阵,推荐用随机变量,比全0好
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1) # 定义偏置项
Wx_plus_b = tf.matmul(inputs, Weights) + biases # 未被激活
if activation_function is None: # 线性的不需要激活函数
output = Wx_plus_b
else:
output = activation_function(Wx_plus_b) # 需要激活函数
return output
'''构建数据'''
x_data = np.linspace(-1, 1, 300)[:, np.newaxis] # newaxis = None,添加维度,变成矩阵的形式
noise = np.random.normal(0, 0.05, x_data.shape) # 添加噪点,让它不完全拟合原来的函数
y_data = np.square(x_data) + 0.5 + noise # 定义的y
'''定义一个输入层(1个神经元),隐藏层(10个神经元),输出层(1个神经元)的简单神经网络'''
'''xs,ys存在的意义是可配置,不把程序写死,解耦,这样可以改变模型的输入值,直接传不方便封装,模型就只能对x_data,y_data进行预测'''
xs = tf.placeholder(tf.float32, (None, 1)) # 输给train_step的值,xs,ys,这里的None后面就是batch_size,None表示随意什么值
ys = tf.placeholder(tf.float32, (None, 1)) # placeholder的作用是用来穿数据的,1是x_data,y_data的属性是1
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# 定义layer 1,调用添加层函数,传入数据:输入数据,输如神经元个数,输出神经元个数(从第一层进入隐藏层,一个进去,10个出来)
# 定义激活函数relu,相当于用10条直线去拟合一个抛物线
prediction = add_layer(l1, 10, 1, activation_function=None)
# 定义输出层,也就是预测曾,传入从隐藏层输出的10个神经元,传出prediction层输出的1个神经元,激活函数默认线性
'''定义损失函数'''
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data-prediction), # 真实值减去预测数据的平方求和再平均
reduction_indices=[1])) # reduction_indices=[1]表示结果压缩的方向,1表示列方向压缩
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
# 采用梯度下降的优化算法以0.1的学习率(优化的步长取值)每训练一次,对误差进行更正或提升,下次会有更好的结果
'''所有变量初始化,并启用会话设置'''
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)
fig = plt.figure() # 生成一个图片框
ax = fig.add_subplot(1, 1, 1) # 给图片添加编号
ax.scatter(x_data, y_data) # 把原图生成散点图
plt.ion() # show之后不暂停
plt.show() # 显示
for i in range(10000): # train_step10000次
# 这里我们可以采用小步骤执行,一次不处理全部的数据,可以解决并行数据量大
sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
if i % 100 == 0:
# print(sess.run(loss, feed_dict={xs: x_data, ys: y_data})) 这个是显示真实值
try:
ax.lines.remove(lines[0]) # 先抹除第一条线,如果没有再继续进行下面的
except Exception:
pass
prediction_value = sess.run(prediction, feed_dict={xs: x_data}) # 预测值
lines = ax.plot(x_data, prediction_value, 'r-', lw=5) # 把x_data和prediction_value用红色的线显示出来,宽度为5
'''但是动态生成一次要抹掉一次,否则就会一直保存在图上'''
plt.pause(0.1) # 暂停0.1秒再继续
'''优化器Optimizer加速神经网络训练'''
'''
计算量太大了
最基础的方法是---Stochatic Gradient Descent(SGD)随机梯度下降
一次训练全部数据数据量太大,所以采用mini batch,每次使用一小部分训练数据调参
1.传统的权重W = W(原始的)+(-Learning rate)*dx(校正值)
2.Momentum的更新方法:m = b1*m-Learning rate * dx ; W = W + m
3.AdaGrad的方法: v = v + dx^2 , W = W - Learning rate*dx/v^(1/2),依赖于学习率,每次会有不同的学习率
4.RMSProp的更新方法:Momentum(m=b1*m-Learning rate*dx)+AdaGrad(v=v+dx^2)---> v=b1*v+(1-b1)*dx^2 ; W = W-Learning rate*dx/v^(1/2)
5.Adam优化器:
m = b1 * m + (1-b1) * dx --------> Momentum(下坡属性)
v = b2 * v + (1-b2) * dx^2-------> AdaGard(阻力属性)
W = W - Learning rate * m/v^(1/2)--->m和v同时考虑在内
迅速收敛
'''
Overfitting 也被称为过度学习,过度拟合。 它是机器学习中常见的问题。 举个Classification(分类)的例子。
图中黑色曲线是正常模型,绿色曲线就是overfitting模型。尽管绿色曲线很精确的区分了所有的训练数据,但是并没有描述数据的整体特征,对新测试数据的适应性较差。
举个Regression (回归)的例子,
第三条曲线存在overfitting问题,尽管它经过了所有的训练点,但是不能很好的反应数据的趋势,预测能力严重不足。 TensorFlow提供了强大的dropout方法来解决overfitting问题。
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer
# load data
digits = load_digits()
X = digits.data
y = digits.target
y = LabelBinarizer().fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.3)
def add_layer(inputs, in_size, out_size, layer_name, activation_function=None, ):
# add one more layer and return the output of this layer
Weights = tf.Variable(tf.random_normal([in_size, out_size]))
biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, )
Wx_plus_b = tf.matmul(inputs, Weights) + biases
'''here to dropout'''
Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob)
if activation_function is None:
outputs = Wx_plus_b
else:
outputs = activation_function(Wx_plus_b, )
tf.summary.histogram(layer_name + '/outputs', outputs)
return outputs
# define placeholder for inputs to network
keep_prob = tf.placeholder(tf.float32)
xs = tf.placeholder(tf.float32, [None, 64]) # 8x8
ys = tf.placeholder(tf.float32, [None, 10])
# add output layer
l1 = add_layer(xs, 64, 50, 'l1', activation_function=tf.nn.tanh)
prediction = add_layer(l1, 50, 10, 'l2', activation_function=tf.nn.softmax)
# the loss between prediction and real data
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
reduction_indices=[1])) # loss
tf.summary.scalar('loss', cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
sess = tf.Session()
merged = tf.summary.merge_all()
# summary writer goes in here
train_writer = tf.summary.FileWriter("logs/train", sess.graph)
test_writer = tf.summary.FileWriter("logs/test", sess.graph)
# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
init = tf.initialize_all_variables()
else:
init = tf.global_variables_initializer()
sess.run(init)
for i in range(500):
# here to determine the keeping probability
sess.run(train_step, feed_dict={xs: X_train, ys: y_train, keep_prob: 0.5})
if i % 50 == 0:
# record loss
train_result = sess.run(merged, feed_dict={xs: X_train, ys: y_train, keep_prob: 1})
test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test, keep_prob: 1})
train_writer.add_summary(train_result, i)
test_writer.add_summary(test_result, i)
训练中keep_prob=1时,就可以暴露出overfitting问题。keep_prob=0.5时,dropout就发挥了作用。 我们可以两种参数分别运行程序,对比一下结果。
当keep_prob=1时,模型对训练数据的适应性优于测试数据,存在overfitting,输出如下: 红线是 train 的误差, 蓝线是 test 的误差.
当keep_prob=0.5时效果好了很多,输出如下:
如果dropout之后还是不够理想可以尝试改小梯度下降的学习率。