tensorflow入门学习,打造自己的工具库,将构建神经层动作抽象为可复用python库(12)

仔细观察第六节的线性回归代码第11节的非线性回归代码,发现构建神经层的流程都是大同小异的,只是某些具体数据有些差异,这很适合写成函数,以后再创建神经层就方便多了,可以直接将其像普通 python 库一样导入使用。

构建神经层的流程


首先,把第 6 节和第 11 节的构建神经层代码截取出来。

########## 第 6 节 ##########
w = tf.Variable(tf.random_uniform([1], -1.0, 1.0))
b = tf.Variable(tf.zeros([1]))
y = w*xdata + b

########## 第 11 节 ##########
# 隐藏层
w1 = tf.Variable(tf.random_normal([1, 10])) 
b1 = tf.Variable(tf.zeros([1, 10]) + 0.1) 
l1 = tf.nn.relu(tf.matmul(x, w1) + b1)
# 输出层
w2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
y = tf.matmul(l1, w2) + b2

发现流程是一样的,都是按照公式 y = wx + b 构建的,不同的只有初始化值和形状而已,可能还有激活函数不一样。这样很适合将构建神经层的动作,写成一个函数。

打造自己的工具,将构建神经层写成函数


经过上面的分析,我们的函数接口可以按照下面定义。

def AddLayer(inputLayer,                # 输入层
             inputSize,                 # 输入层的纬度
             outputSize,                # 输出层的纬度
             activation_function,       # 激活函数
             name                       # 该层的名字
            )

根据 inputSize 和 outputSize 可以构建出权值和偏置,权值统一按照 tf.random_normal 方法初始化,偏置统一初始化为 0.1。然后,如果没有激活函数,则直接返回y = wx + b,如果有激活函数,则将输出经过激活函数再返回,函数可以如下写:

#encoding=utf8
import tensorflow as tf

def AddLayer(inputLayer,                # 输入层
             inputSize,                 # 输入层的纬度
             outputSize,                # 输出层的纬度
             activation_function=None,  # 激活函数,默认 None
             name='layer'               # 该层的名字,默认 layer
            ):
    w = tf.Variable(tf.random_normal([inputSize, outputSize])) 
    b = tf.Variable(tf.zeros([1, outputSize]) + 0.1)
    res = tf.matmul(inputLayer, w) + b
    if None == activation_function:
        return res
    else:
        return activation_function(res)

新建一个文件 personalTools.py,将以上代码写入,这样就完成了我们自己的一个工具,以后可以像导入其他 python 库一样使用它。

使用自己的工具,重写非线性回归代码


首先将personalTools.py复制到工作目录(即与主代码同目录),然后导入AddLayer函数,过程和 python 标准库一致。

from personalTools import AddLayer

要修改的是神经层构建部分,即将

# 隐藏层
w1 = tf.Variable(tf.random_normal([1, 10])) 
b1 = tf.Variable(tf.zeros([1, 10]) + 0.1) 
l1 = tf.nn.relu(tf.matmul(x, w1) + b1)
# 输出层
w2 = tf.Variable(tf.random_normal([10, 1]))
b2 = tf.Variable(tf.zeros([1, 1]) + 0.1)
y = tf.matmul(l1, w2) + b2  

修改为

# 隐藏层
layer1 = AddLayer(x, 1, 10, tf.nn.relu)
# 输出层
y = AddLayer(layer1, 10, 1) 

重写后的代码为:

#encoding=utf8
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt  
from personalTools import AddLayer

# 构建数据
xdata = np.linspace(-1,1,200, dtype=np.float32)[:, np.newaxis]
noise = np.random.normal(0, 0.05, xdata.shape).astype(np.float32)
ydata = np.square(xdata) - 0.5 + noise

# 绘制构建的数据

fig = plt.figure()
plt.ylim(-1,1)
ax = fig.add_subplot(1,1,1)
ax.scatter(xdata, ydata)
plt.ion()#本次运行请注释,全局运行不要注释
plt.show()

# 构建网络
x = tf.placeholder(tf.float32)
y_ = tf.placeholder(tf.float32)
    # 隐藏层
layer1 = AddLayer(x, 1, 10, tf.nn.relu)
    # 输出层
y = AddLayer(layer1, 10, 1) 
    # 定义损失函数和训练方法
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y - y_),
                     reduction_indices=[1]))
train = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

# 初始化
init = tf.global_variables_initializer()

# 训练
with tf.Session() as sess:
    sess.run(init)
    for i in range(1001):
        sess.run(train, feed_dict={x:xdata, y_:ydata})
        if i%50 == 0:
            print sess.run(loss, feed_dict={x:xdata, y_:ydata})
            try:
                ax.lines.remove(lines[0])
            except Exception:
                pass
            lines = ax.plot(xdata, sess.run(y, feed_dict={x:xdata}), 'r-', lw=2)
            plt.pause(0.1)

运行之,发现成功了。

$ python t.py 
0.0070467605
0.0044801924
0.0035597545
0.003196882
0.0030136926
0.0028756743
0.0027896028
0.0027230275
...
阅读更多:   tensorflow
添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif