前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >未来的人工智能将有神经元结构?谷歌 Tensorflow 系统已经实现

未来的人工智能将有神经元结构?谷歌 Tensorflow 系统已经实现

作者头像
企鹅号小编
发布2018-01-22 10:58:22
5960
发布2018-01-22 10:58:22
举报
文章被收录于专栏:人工智能人工智能

神经网络是Tensorflow最擅长的机器学习领域。TensorFlow拥有一套符号引擎,它使得训练复杂模型变得更简单和方便。通过这套符号引擎,我们能够实现许多的模型结构和算法。

本文中,我们将会覆盖以下内容:

神经网络的基本概念;

神经网络用于回归非线性合成函数;

使用非线性回归预测汽车燃料效率;

学习葡萄酒分类——一种多类分类。

5.1.1 人工神经元

人工神经元就是使用一个数学函数来对生物的神经元建模。

简单来说,一个人工神经元就是接受一个或者多个输入(训练数据),对它们加和,并产生一个输出。一般来说,这里面的加和指的是加权求和(每个输入乘上权重,并加上一个偏差),然后将加和的输入传递给一个非线性函数(一般称作激活函数或者转移函数)。

1.最简单的人工神经元——感知器

感知器是实现人工神经元最简单的方法,它的历史可以追溯到20世纪50年代,在20世纪60年代的时候,首次被实现。

简单来说,感知器就是一个二元分类函数,它将输入映射到一个二元输出,如图5-1所示。

图5-1 单层感知器

2.感知器算法

简化版的感知器算法如下:

以一个随机分布初始化权值和偏差(通常比较小);

选择一个输入向量,并将其放入神经网络中;

将输入与权重相乘,并加上偏差,计算网络的输出y';

感知器的函数如下:

如果y′≠y,将权重wi加上Δw=yxi;

返回第步。

5.1.2 神经网络层

我们可以对单层的感知器进行泛华,将它们堆积起来,并互相连接,如图5-2所示。但这就带来一个问题,这样的线性组合出来的模型还只是一个线性分类器,对于复杂的非线性分类,这种方式并不能正确拟合,这个问题需要激活函数来解决。

1.神经网络激活函数

单独的单变量线性分类器并不能带来神经网络的强悍性能。就算那些不是很复杂的机器学习问题都会涉及多变量和非线性,所以我们常常要用其他的转移函数来替代感知器中原本的转移函数。

图5-2 连接单层感知器

有很多非线性函数可以用来做激活函数,从而表征不同的非线性模型。在输入同样的变量的时候,不同的激活函数有不同的响应。常用的激活函数如下:

Logistic:典型的激活函数,在计算分类的概率时非常有用。

Tanh:跟Sigmoid函数很像,但是范围是[−1,1],而不是[0,1]。

Relu:修正线性函数,该函数主要是为了对抗梯度消失。也就是当梯度反向传播到第一层的时候,梯度容易趋近于0或者一个极小值。

{-:-}f(x)=max(0, x)

在我们计算总的误差的时候,因为是一整个函数作用于输入数据,所以我们要调整这个方程中的所有变量,来最小化方程。

怎样最小化误差呢?正如我们在优化部分所学,我们通过损失函数的梯度来最小化误差。

如果我们的网络拥有多层权重和转移函数,我们最终需要通过链式法则来求导所有参数的梯度。

2.梯度和反向传播算法

在感知器的学习阶段,我们按照每个权重对误差的“责任”,按比例调整权重。

在更复杂的网络中,误差的责任被分散在整个结构的所有操作之中。

3.最小化损失函数:梯度下降

我们由图5-3理解一下损失函数。

4.神经网络的选择-分类vs回归

神经网络既可以被用于回归问题,也可以被用于分类问题。不同的地方在于结构的最后一层。如果需要的结果是一个数值,那么就不要连接标准函数,如 sigmoid。如果是这样的话,我们得到的就是一个连续值。

图5-3 梯度下降

5.1.3 有用的库和方法

本章中我们会用到TensorFlow中一些新的函数,下面是我们需要的最重要的函数:

1.TensorFlow激活函数

最常用的激活函数如下:

tf.sigmoid(x):标准的sigmoid函数;

tf.tanh(x):双曲正切函数;

TensorFlow中其他的函数:

tf.softsign(x):返回x/(abs(x)+1);

2.TensorFlow中损失优化方法

tf.train.GradientDescentOptimizer(learningrate, uselocking, name):原始梯度下降方法,唯一参数就是学习率。

tf.train.AdagradOptimizer:自适应调整学习率,累加历史梯度的平方,作为分母,防止有些方向的梯度值过大,提高优化效率,善于处理稀疏梯度。

tf.train.AdadeltaOptimizer:扩展AdaGrad优化方法,只累加最近的梯度值,而不对整个历史上的梯度值进行累加。

tf.train.AdamOptimizertf.train.AdamOptimizer. (learningrate, beta1, beta2, epsilon, use locking, name):梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。Adam是自适应矩估计(Adaptive Moment Estimation)的首字母缩写。

3.Sklearn预处理函数

我们看一些下面的Sklearn数据预处理函数:

preprocessing.StandardScaler():数据正规化(Normalization)是机器学习估计的一个常见要求,为了模型能更好地收敛,我们通常会将数据集预处理到一个零均值单位方差的高斯状分布。通常,我们会将数据的各个维度都减去它的均值,然后乘上一个非零的数。这个非零的数就是数据集的标准差。对于该任务,我们直接使用StandardScaler,它已经实现了我们上面提到的操作。它也保留了变换操作,让我们可以直接用在测试集上。

StandardScaler .fit_transform():将数据调整到所需要的形式。StandardScaler对象会存储数据变化的变量,这样我们可以把数据解正规化到原先的格式。

crossvalidation.traintest_split:该方法能够将数据集分割成训练集和测试集。我们只需要提供两者的比例,该方法能够自动帮我们处理。

5.2 例1——非线性模拟数据回归

人工神经网络的应用包含了很多的分类任务,但是事实上,很多这些分类任务都是用回归来实现的。

分类和回归的网络结构差的并不多,都可以使用多变量的输入,以及线性或者非线性的激活函数。

在一些例子中,唯一要变的就是在输出层,连接上Sigmoid状的函数,该函数能够表征结果为各个类别的可能性。

在第一个例子中,我们使用一个简单的带噪声的二次方程生成样本。模型我们使用带一个隐含层的神经网络,然后检测预测值跟真实值的距离远近。

5.2.1 数据集描述和加载

本例中,我们使用生成的数据集,这跟第3章线性回归类似。

我们这次选择的方程是一个二次方程,并加上随机噪声,这有助于帮助我们测试回归的泛化能力。

核心代码如下:

import numpy as np

trainsamples = 200

testsamples = 60

dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()

5.2.2 数据集预处理

本例中的数据集不需要预处理,因为它是我们人工生成的,具有更好的性能,比如能够保证数据范围是(−1,1)。

5.2.3 模型结构——损失函数描述

本例中的损失函数使用均方误差,由以下代码实现:

cost = tf.pow(py_x-Y, 2)/(2)

5.2.4 损失函数优化器

本例中,我们使用梯度下降作为损失函数优化器,可以用以下代码实现:

train_op = tf.train.AdamOptimizer(0.5).minimize(cost)

5.2.5 准确度和收敛测试

predict_op = tf.argmax(py_x, 1)

cost1 += sess.run(cost, feed_dict=) / testsamples

5.2.6 完整源代码

完整源代码如下:

import tensorflow as tf

import numpy as np

from sklearn.utils import shuffle

%matplotlib inline

import matplotlib.pyplot as plt

trainsamples = 200

testsamples = 60

#Here we will represent the model, a simple imput, a hidden layer of

sigmoid activation

def model(X, hidden_weights1, hidden_bias1, ow):

return tf.matmul(hidden_layer, ow)

dsX = np.linspace(-1, 1, trainsamples + testsamples).transpose()

plt.figure() # Create a new figure

plt.title('Original data')

plt.scatter(dsX,dsY) #Plot a scatter draw of the datapoints

X = tf.placeholder("float")

Y = tf.placeholder("float")

# Create first hidden layer

hw1 = tf.Variable(tf.random_normal([1, 10], stddev=0.1))

# Create output connection

ow = tf.Variable(tf.random_normal([10, 1], stddev=0.0))

# Create bias

b = tf.Variable(tf.random_normal([10], stddev=0.1))

model_y = model(X, hw1, b, ow)

# Cost function

cost = tf.pow(model_y-Y, 2)/(2)

# construct an optimizer

train_op = tf.train.GradientDescentOptimizer(0.05).minimize(cost)

# Launch the graph in a session

with tf.Session() as sess:

tf.initialize_all_variables().run() #Initialize all variables

for i in range(1,100):

dsX, dsY = shuffle (dsX.transpose(), dsY) #We randomize the samples

to mplement a better training

trainX, trainY =dsX[0:trainsamples], dsY[0:trainsamples]

for x1,y1 in zip (trainX, trainY):

sess.run(train_op, feed_dict=)

testX, testY = dsX[trainsamples:trainsamples + testsamples],

dsY[0:trainsamples:trainsamples+testsamples]

cost1=0.

for x1,y1 in zip (testX, testY):

cost1 += sess.run(cost, feed_dict=) /

testsamples

if (i%10 == 0):

print "Average cost for epoch " + str (i) + ":" + str(cost1)

5.2.7 结果描述

生成的人工数据的散点图如图5-4所示。

图5-4 人工数据散点图

由以下每次迭代的结果,我们知道该实现结果非常好,甚至在第一次迭代的时候就取得了不错的结果。

Average cost for epoch 9:[[ 0.0007379]]

5.3 例2——通过非线性回归,对汽车燃料效率建模

本例中,我们会进入一个新的领域:解决非线性问题。该领域是神经网络附加值最大的领域。开始该旅程之前,我们会对几个汽车型号的燃料效率建模。该问题的输入是多个变量,只有非线性模型才能取得比较好的结果。

5.3.1 数据集描述和加载

对该问题,我们会分析一个著名的、标准的、数据组织得很好的数据集。我们有一个多变量的输入(有连续的,也有离散的),预测每加仑英里数(mpg)。

这是一个玩具级例子,但是这个例子会铺开通往更复杂问题的道路。而且该例子还有个好处,就是被大量研究过。

数据集由如下的列组成。

mpg:每加仑英里数,连续。

cylinders:气缸,多值离散。

displacement:排量,连续。

horsepower:马力,连续。

weight:车重,连续。

acceleration:加速度,连续。

model year:年份,多值离散。

origin:产地,多值离散。

car name:车名,字符串(不会被使用)。

我们不会对该数据做详细的分析,我们只是想看一下每一个连续的变量都跟目标变量的增减相关,如图5-5所示。

图5-5 不同的变量和燃烧效率的关系散点图

5.3.2 数据预处理

本例中,我们会使用一个前面描述的sklearn中的StandardScaler对象:

scaler = preprocessing.StandardScaler()

Xtrain = scaler.fittransform(X_train)

5.3.3 模型架构

我们需要建立的是一个多变量输入,单变量输出的前向神经网络,如图5-6所示。

图5-6 模型架构

5.3.4 准确度测试

我们用以下代码实现准确度测试:

score =

metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)),

y_test)

print(" Total Mean Squared Error: " + str(score))

5.3.5 结果描述

Step #99, avg. train loss: 182.33624

Step #199, avg. train loss: 25.09151

Step #300, epoch #1, avg. train loss: 11.92343

Step #400, epoch #1, avg. train loss: 11.20414

Step #500, epoch #1, avg. train loss: 5.14056

5.3.6 完整源代码

完整源代码如下:

%matplotlib inline

import matplotlib.pyplot as plt

import pandas as pd

from sklearn import datasets, cross_validation, metrics

from sklearn import preprocessing

from tensorflow.contrib import skflow

# Read the original dataset

df = pd.read_csv("data/mpg.csv", header=0)

# Convert the displacement column as float

df['displacement']=df['displacement'].astype(float)

# We get data columns from the dataset

# First and last (mpg and car names) are ignored for X

X = df[df.columns[1:8]]

y = df['mpg']

plt.figure() # Create a new figure

for i in range (1,8):

number = 420 + i

ax1.locator_params(nbins=3)

ax1 = plt.subplot(number)

plt.title(list(df)[i])

ax1.scatter(df[df.columns[i]],y) #Plot a scatter draw of the

datapoints

plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)

# Split the datasets

X_train, X_test, y_train, y_test = cross_validation.train_test_split(X, y,

test_size=0.25)

# Scale the data for convergency optimization

scaler = preprocessing.StandardScaler()

# Set the transform parameters

X_train = scaler.fit_transform(X_train)

# Build a 2 layer fully connected DNN with 10 and 5 units respectively

regressor = skflow.TensorFlowDNNRegressor(hidden_units=[10, 5],

steps=500, learning_rate=0.051, batch_size=1)

# Fit the regressor

regressor.fit(X_train, y_train)

# Get some metrics based on the X and Y test data

score =

metrics.mean_squared_error(regressor.predict(scaler.transform(X_test)),

y_test)

print(" Total Mean Squared Error: " + str(score))

5.4 例3——多类分类:葡萄酒分类

本部分,我们会处理一个更复杂的数据集,预测葡萄酒的原产地。

5.4.1 数据集描述和加载

这个数据集包含了3种不同起源的葡萄酒,每个数据有13个属性。这些葡萄酒都由意大利制造,但是原产地不一样。

数据变量:

Alcohol:酒精度。

Malic acid:苹果酸。

Ash:灰。

Alcalinity of ash:灰分的碱度。

Magnesium:镁含量。

Total phenols:总酚类。

Flavanoids:黄烷类。

Nonflavanoid phenols:非类黄烷酚。

Proanthocyanins:原花青素。

Color intensity:颜色强度。

Hue:色相。

OD280/OD315 of diluted wines:稀释葡萄酒的OD280 / OD315。

Proline:脯氨酸。

读取该数据集,我们只需要调用pandas库即可。

df = pd.read_csv("./wine.csv", header=0)

5.4.2 数据集预处理

因为该csv文件从1开始,为数据减去该偏差:

y = df['Wine'].values-1

对于其结果,我们使用一位有效编码:

Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis =

1 , name = "a").eval()

不同变量跟原产地关系散点图如图5-7所示。同样,我们会选择预先打乱数据:

图5-7 不同变量跟原产地关系散点图

X, Y = shuffle (X, Y)

scaler = preprocessing.StandardScaler()

X = scaler.fit_transform(X)

5.4.3 模型架构

该模型只需要一个单层的全链接神经网络:

x = tf.placeholder(tf.float32, [None, 12])。

W = tf.Variable(tf.zeros([12, 3]))。

b = tf.Variable(tf.zeros([3]))。

5.4.4 损失函数描述

我们选择交叉熵作为损失函数:

y_ = tf.placeholder(tf.float32, [None, 3])

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),

reduction_indices=[1]))

5.4.5 损失函数优化器

我们又一次选择梯度下降作为损失函数的优化器。

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)

5.4.6 收敛性测试

在收敛性测试中,我们将正确预测的结果算作1,错误预测的结果算作0,计算它们的均值,作为该模型的准确度。

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print(accuracy.eval())

5.4.7 结果描述

正如我们所见,准确度会随着迭代的次数而波动,但一直是一个大于90%的准确率,远高于30%的基准线(如果我们随机猜测一个0~3的结果)。

0.973684

0.921053

0.921053

0.947368

0.921053

5.4.8 完整源代码

完整源代码如下:

sess = tf.InteractiveSession()

import pandas as pd

# Import data

from sklearn.utils import shuffle

from sklearn import preprocessing

flags = tf.app.flags

FLAGS = flags.FLAGS

df = pd.read_csv("./wine.csv", header=0)

print (df.describe())

#df['displacement']=df['displacement'].astype(float)

X = df[df.columns[1:13]].values

y = df['Wine'].values-1

Y = tf.one_hot(indices = y, depth=3, on_value = 1., off_value = 0., axis =

1 , name = "a").eval()

X, Y = shuffle (X, Y)

scaler = preprocessing.StandardScaler()

X = scaler.fit_transform(X)

# Create the model

x = tf.placeholder(tf.float32, [None, 12])

W = tf.Variable(tf.zeros([12, 3]))

b = tf.Variable(tf.zeros([3]))

# Define loss and optimizer

y_ = tf.placeholder(tf.float32, [None, 3])

cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y),

reduction_indices=[1]))

train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy)

# Train

tf.initialize_all_variables().run()

for i in range(100):

X,Y =shuffle (X, Y, random_state=1)

Xtr=X[0:140,:]

Ytr=Y[0:140,:]

Xt=X[140:178,:]

Yt=Y[140:178,:]

Xtr, Ytr = shuffle (Xtr, Ytr, random_state=0)

batch_xs, batch_ys = Xtr , Ytr

train_step.run()

cost = sess.run (cross_entropy, feed_dict=)

# Test trained model

correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))

accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

print(accuracy.eval())

5.5 小结

在本章中,我们开始学习TensorFlow最强的功能:神经网络模型。

通过使用生成模型和实验模型,我们同时实现了神经网络的回归和分类。

在下一章中,我们将会深入新的模型结构,并且将神经网络模型用到其他的知识领域,如将卷积神经网络用于计算机视觉。

-

本文摘自《TensorFlow机器学习项目实战》

本文来自企鹅号 - 邮书媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文来自企鹅号 - 邮书媒体

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档