以监督学习为例,假设我们有训练样本集 ( x ( i ) , y ( i ) ) (x^{(i)},y^{(i)}) (x(i),y(i)),那么神经网络算法能够提供一种复杂且非线性的假设模型 h w , b ( x ) h_{w,b}(x) hw,b(x),它具有参数W,b,可以以此参数来拟合我们的数据。
为了描述神经网络,我们先从最简单的神经网络讲起,这个神经网络仅由一个“神经元”构成,以下即是这个“神经元”的图示
后文我们会介绍有多个神经元的神经网络,因此单个神经元模型我们后面会简化成如下图:
这个“神经元”是一个以 x 1 , x 2 , x 3 x_1,x_2,x_3 x1,x2,x3及截距 +1 为输入值的运算单元,其输出为
h w , b ( x ) = f ( W T X ) = f ( ∑ i = 1 3 W i x i + b ) h_{w,b}(x)=f(W^TX)=f(\sum_{i=1}^{3}W_ix_i+b) hw,b(x)=f(WTX)=f(i=1∑3Wixi+b)
其中函数f有 f : R ↦ R f:R \mapsto R f:R↦R被称为“激活函数”。 在本教程中,我们选用sigmoid函数作为”激活函数”
f ( ⋅ ) s i g m o i d f(⋅)sigmoid f(⋅)sigmoid函数: f ( z ) = 1 1 + e x p ( − z ) f(z)=\frac{1}{1+exp(-z)} f(z)=1+exp(−z)1
sigmoid函数图像如下:
可以看出,这个单一“神经元”的输入-输出映射关系其实就是一个逻辑回归(logistic regression)。
此外,你也可以选择双曲正切函数(tanh). tanh函数:
f ( z ) = t a n h ( z ) = e z − e − z e z + e − z f(z)=tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}} f(z)=tanh(z)=ez+e−zez−e−z
tanh函数的图像如下:
tanh(z) 函数是sigmoid函数的一种变体,它的取值范围为 [−1,1] ,而不是sigmoid函数的 [0,1]。
注意:这里我们不再令 x 0 = 1 x_0=1 x0=1 。取而代之,我们用单独的参数 b 来表示截距。
最后要说明的是,有一个等式我们以后会经常用到:
如果选择 f ( z ) = 1 / ( 1 + e x p ( − z ) ) f(z)=1/(1+exp(−z)) f(z)=1/(1+exp(−z)),也就是sigmoid函数,那么它的导数就是
f ′ ( z ) = = f ( z ) ( 1 − f ( z ) ) f'(z)==f(z)(1-f(z)) f′(z)==f(z)(1−f(z))
如果选择tanh函数,那它的导数就是
f ′ ( z ) = 1 − f ( z ) 2 f'(z)=1-f(z)^2 f′(z)=1−f(z)2
你可以根据sigmoid(或tanh)函数的定义自行推导这个等式。
神经网络模型
所谓神经网络就是将许多个单一“神经元”联结在一起,这样,一个“神经元”的输出就可以是另一个“神经元”的输入。例如,下图就是一个简单的神经网络:
我们使用蓝色圆圈来表示神经网络的输入,标上“+1”的圆圈被称为”’偏置节点”’,也就是截距项。神经网络最左边的一层叫做”’输入层”’,最右的一层叫做”’输出层”’(本例中,输出层只有一个节点)。中间所有节点组成的一层叫做”’隐藏层”’,因为我们不能在训练样本集中观测到它们的值。同时可以看到,以上神经网络的例子中有3个”’输入单元”’(偏置单元不计在内),3个”’隐藏单元”’及一个”’输出单元”’。
实验环境Win10 X64
Python3.6,使用anaconda3虚拟环境
pycharm
实验目的利用神经网络进行对reuters路透社语料库进行文本分类。
实验步骤-
准备实验环境与新建项目,在此不细述
-
在Terminal,输入以下命令安装所需package包
conda activate tensorflow
pip install tensorflow==1.3.0
pip install keras==2.1.2
pip install numpy==1.16.2
- 利用神经网络进行对reuters路透社语料库进行文本分类,导入外包
from __future__ import print_function
import numpy as np
from keras.datasets import reuters
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.utils import np_utils
from keras.preprocessing.text import Tokenizer
- 载入数据
(X_train, y_train), (X_test, y_test) = reuters.load_data(num_words=max_words, test_split=0.2) # 载入路透社语料 #打印
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
运行结果
- 数据预处理
tokenizer = Tokenizer(
nb_words=max_words) # 序列化,取df前1000大 #这里有个非常好玩的事, X_train 里面初始存的是wordindex,wordindex是按照词大小来的(应该是,因为直接就给撇了) #所以这个效率上还是很高的 #转化的还是binary,默认不是用tfidf
X_train = tokenizer.sequences_to_matrix(X_train, mode='binary')
X_test = tokenizer.sequences_to_matrix(X_test, mode='binary')
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
- 特征提取
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
print('Y_train shape:', Y_train.shape)
print('Y_test shape:', Y_test.shape)
运行结果
- 建立模型
model = Sequential() # 第一层 #Dense就是全连接层
model.add(Dense(512, input_shape=(max_words,))) # 输入维度, 512==输出维度
model.add(Activation('relu')) # 激活函数
model.add(Dropout(0.5)) # dropout #第二层
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
# 损失函数设置、优化函数,衡量标准
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
- 训练,交叉验证
history = model.fit(X_train, Y_train,
epochs=nb_epoch, batch_size=batch_size,
verbose=1, validation_split=0.1)
score = model.evaluate(X_test, Y_test,
batch_size=batch_size, verbose=1)
print('\nTest score:', score[0])
print('Test accuracy:', score[1])
运行结果
- 完整代码如下:
from __future__ import print_function
import numpy as np
np.random.seed(1337) # for reproducibility
from keras.datasets import reuters
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.utils import np_utils
from keras.preprocessing.text import Tokenizer
max_words = 1000 # vocab大小
batch_size = 32 # mini_batch_size
nb_epoch = 5 # 大循环次数
print('Loading data...')
(X_train, y_train), (X_test, y_test) = reuters.load_data(num_words=max_words, test_split=0.2) # 载入路透社语料 #打印
print(len(X_train), 'train sequences')
print(len(X_test), 'test sequences')
# 分类数目--原版路透社我记着是10来着,应该是语料用的是大的那个
nb_classes = np.max(y_train) + 1
print(nb_classes, 'classes')
print('Vectorizing sequence data...') # tokenize
tokenizer = Tokenizer(
nb_words=max_words) # 序列化,取df前1000大 #这里有个非常好玩的事, X_train 里面初始存的是wordindex,wordindex是按照词大小来的(应该是,因为直接就给撇了)#所以这个效率上还是很高的
#转化的还是binary,默认不是用tfidf
X_train = tokenizer.sequences_to_matrix(X_train, mode='binary')
X_test = tokenizer.sequences_to_matrix(X_test, mode='binary')
print('X_train shape:', X_train.shape)
print('X_test shape:', X_test.shape)
print('Convert class vector to binary class matrix (for use with categorical_crossentropy)')
Y_train = np_utils.to_categorical(y_train, nb_classes)
Y_test = np_utils.to_categorical(y_test, nb_classes)
print('Y_train shape:', Y_train.shape)
print('Y_test shape:', Y_test.shape)
print('Building model...')
model = Sequential() # 第一层 #Dense就是全连接层
model.add(Dense(512, input_shape=(max_words,))) # 输入维度, 512==输出维度
model.add(Activation('relu')) # 激活函数
model.add(Dropout(0.5)) # dropout #第二层
model.add(Dense(nb_classes))
model.add(Activation('softmax'))
# 损失函数设置、优化函数,衡量标准
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# 训练,交叉验证
history = model.fit(X_train, Y_train,
epochs=nb_epoch, batch_size=batch_size,
verbose=1, validation_split=0.1)
score = model.evaluate(X_test, Y_test,
batch_size=batch_size, verbose=1)
print('\nTest score:', score[0])
print('Test accuracy:', score[1])
最终运行结果:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)