1 激活函数限制
激活函数是在预测时应用于一层神经元的函数。激活函数有以下的限制:
约束1:函数必须连续且定义域是无穷的
约束2:好的激活函数是单调的,不会改变方向
神经网络进行学习时,实际上是在寻找合适的权重配置来给出特定的输出。如果有多个正确答案时,这个问题会变得困难得多。
约束3:好的激活函数是非线性的(扭曲或反转)
约束4:合适的激活函数(及其导数)应该可以高效计算
2 标准隐藏层激活函数
1、基础激活函数 sigmoid 能平滑地将输入从无穷大的空间压缩到 0 到 1 之间。这可以让你把单个神经元的输出解释为一个概率。人们通常在隐藏层和输出层之中使用这种非线性函数。sigmoid 函数能给出不同程度的正相关
2、tanh 函数能完成 sigmoid 一样的工作,只是它的取值在 -1 和 1 之间,这意味着,它可以引入一部分负相关,负相关对于隐藏层来说作用很大
3 标准输出层激活函数
类型1:预测原始数据值(没有激活函数)
给定周围各州的气温,预测科罗拉多州的平均气温。输出结果不在 0 到 1 之间,可以不选择激活函数
类型2:预测不相关的“是”或“否”的概率(sigmoid)
根据输入数据预测团队是否会赢,是否会受伤,以及团队士气是否高涨,适合使用 sigmoid激活函数,它能对每个输出节点分别建模
类型3:预测“哪一个”的概率(softmax)
如 MNIST 数字分类器,预测图像中是哪个数字,需要一个激活函数对 “当出现一个标签的可能性越大时,出现另一个标签的可能性就越小”这一概念进行建模。sofmax 函数比较合适
softmax计算每个输入值的指数形式,除以该层的和,常用于分类问题。softmax 的好处是,神经网络对于一个值的预测越高,它对所有其他值的预测就越低。它增加了信号衰减的锐度,鼓励网络以非常高的概率预测某项输出
使用tanh函数带图relu函数,看效果:
import sys,numpy as np
np.random.seed(1)
from keras.datasets import mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
#维度分别为(60000,28,28),((60000,)
x_train.shape,y_train.shape
#维度分别为(1000,28*28),((1000,)
#功能:降维,进行标准化
images,labels = (x_train[0:1000].reshape(1000,28*28)/255,y_train[0:1000])
#维度是(1000,10)
one_hot_labels = np.zeros((len(labels),10))
#这个是结果的维度(1000,10),在0-9的的对应位置上标记为1,其余位置标记为0
for i,l in enumerate(labels):
one_hot_labels[i][l] = 1
labels = one_hot_labels
test_images = x_test.reshape(len(x_test),28*28)/255
test_labels = np.zeros((len(y_test),10))
for i,l in enumerate(y_test):
test_labels[i][l] = 1
#relu = lambda x:(x>0) * x
#relu2deriv = lambda x:x>0
def tanh(x):
return np.tanh(x)
def tanh2deriv(output):
return 1-(output**2)
#沿着第一维进行求和,保留数组的维度
def softmax(x):
temp = np.exp(x)
return temp/np.sum(temp,axis=1,keepdims=True)
#三层神经网络 layer0 为 784,layer1 隐藏层为 100,layer2 结果层为10
alpha,interations,hidden_size,pixels_per_image,num_labels = (0.02,300,100,784,10)
#初始化权重
weight_0_1 = 0.02*np.random.random((pixels_per_image,hidden_size)) - 0.01
weight_1_2 = 0.2*np.random.random((hidden_size,num_labels)) - 0.1
batch_size = 100
for j in range(interations):
error,correct_cnt = (0.0,0)
for i in range(int(len(images)/batch_size)):
batch_start,batch_end = ((i*batch_size),((i+1)*batch_size))
#维度(100,784)
layer_0 = images[batch_start:batch_end]
layer_1 = tanh(np.dot(layer_0,weight_0_1))
dropout_mask = np.random.randint(2,size=layer_1.shape)
layer_1 *= dropout_mask * 2
layer_2 = np.dot(layer_1,weight_1_2)
error += np.sum((labels[batch_start:batch_end] - layer_2)**2)
for k in range(batch_size):
correct_cnt += int(np.argmax(layer_2[k:k+1]) == np.argmax(labels[batch_start+k:batch_start+k+1]))
#取平均权重
layer_2_delta = (labels[batch_start:batch_end] - layer_2)/batch_size
layer_1_delta = layer_2_delta.dot(weight_1_2.T)*tanh2deriv(layer_1)
layer_1_delta *= dropout_mask
weight_1_2 += alpha * layer_1.T.dot(layer_2_delta)
weight_0_1 += alpha * layer_0.T.dot(layer_1_delta)
test_correct_cnt = 0
for i in range(len(test_images)):
layer_0 = test_images[i:i+1]
layer_1 = tanh(np.dot(layer_0,weight_0_1))
layer_2 = np.dot(layer_1,weight_1_2)
test_correct_cnt += int(np.argmax(layer_2) == np.argmax(test_labels[i:i+1]))
if (j%10 == 0):
sys.stdout.write("\n" + "I:" + str(j) + " Test-Acc:" +str(test_correct_cnt/float(len(test_images))) + \
" Train-Acc:" +str(correct_cnt/float(len(images))))
4 参考资料
《深度学习图解》