神經網路是一個被廣泛運用於圖像識別、語音識別、自然語言處理等領域的機器學習模型。然而,神經網路中原始的線性模型缺乏處理非線性關係的能力,這意味著不同特徵之間的混合效應無法被捕捉到。因此,在神經網路中引入非線性是至關重要的。
一、激活函數
激活函數是神經網路中引入非線性的最基礎的方法之一。前面我們提到,線性模型可以處理每個特徵的影響,但是無法捕捉特徵之間的協同關係。而激活函數不僅在單個神經元內引入了非線性,同時也使得不同神經元之間出現非線性交互。因此,如果沒有激活函數,神經網路將仍然是一個線性模型。
下面是一個使用Sigmoid作為激活函數的代碼示例:
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
class NeuralNetwork:
def __init__(self, num_inputs, hidden_layers_sizes, num_outputs):
self.weights = []
prev_layer_size = num_inputs
for layer_size in hidden_layers_sizes:
w = np.random.rand(prev_layer_size, layer_size)
self.weights.append(w)
prev_layer_size = layer_size
w = np.random.rand(prev_layer_size, num_outputs)
self.weights.append(w)
def feedforward(self, inputs):
a = inputs
for w in self.weights:
z = np.dot(a, w)
a = sigmoid(z)
return a
inputs = np.array([1, 2, 3])
network = NeuralNetwork(3, [4, 5], 2)
output = network.feedforward(inputs)
print(output)
其中,新建了一個NeuralNetwork類,用於描述具有三個輸入,兩個輸出的多層感知機模型,並且hidden_layers_sizes參數表示隱藏層有4個神經元和5個神經元,使用sigmoid函數作為激活函數。
二、卷積神經網路
卷積神經網路(Convolutional Neural Network,CNN)是一種使用卷積方式進行特徵提取的神經網路。卷積操作可以看成是一種局部的操作,在一定程度上採集的只是特徵的一部分信息,因此在網路中引入了非線性。此外,池化操作等也可以看成是一種非線性變換,通過降維和篩選等操作強化了特徵的表達力。
下面是一個簡單的卷積神經網路的代碼實現(這裡使用MNIST數據集):
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
from keras.utils import np_utils
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1) / 255.0
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1) / 255.0
y_train = np_utils.to_categorical(y_train, 10)
y_test = np_utils.to_categorical(y_test, 10)
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=32, epochs=10, verbose=1, validation_data=(x_test, y_test))
在此代碼片段中,使用Keras工具包和MNIST數據集搭建了一個簡單的卷積神經網路,並且使用relu函數作為激活函數。網路結構包括兩層卷積、兩層池化和兩層全連接。
三、遞歸神經網路
遞歸神經網路(Recurrent Neural Network,RNN)是一種能夠利用序列信息的神經網路。由於它們的結構中包含一個或多個循環層,所以可以捕獲時間序列中的非線性關係,從而引入了非線性。在許多自然語言處理任務中,包括語音識別和文本生成等,遞歸神經網路是非常流行的選擇。
下面是一個簡單的用於文本生成的遞歸神經網路的代碼實現(這裡使用Shakespeare數據集):
import numpy as np
from keras.layers import Dense, Activation, LSTM
from keras.models import Sequential
from keras.optimizers import RMSprop
from keras.utils.data_utils import get_file
path = get_file('shakespeare.txt', origin='https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt')
text = open(path).read().lower()
print('corpus length:', len(text))
chars = sorted(list(set(text)))
print('total chars:', len(chars))
char_indices = dict((c, i) for i, c in enumerate(chars))
indices_char = dict((i, c) for i, c in enumerate(chars))
maxlen = 40
step = 3
sentences = []
next_chars = []
for i in range(0, len(text) - maxlen, step):
sentences.append(text[i: i + maxlen])
next_chars.append(text[i + maxlen])
print('nb sequences:', len(sentences))
x = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool)
y = np.zeros((len(sentences), len(chars)), dtype=np.bool)
for i, sentence in enumerate(sentences):
for t, char in enumerate(sentence):
x[i, t, char_indices[char]] = 1
y[i, char_indices[next_chars[i]]] = 1
model = Sequential()
model.add(LSTM(128, input_shape=(maxlen, len(chars))))
model.add(Dense(len(chars)))
model.add(Activation('softmax'))
optimizer = RMSprop(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer=optimizer)
model.fit(x, y, batch_size=128, epochs=10)
該代碼片段中,使用Keras搭建了一個只含有一個LSTM循環層的遞歸神經網路。該網路用於在莎士比亞文本數據集上進行訓練,從而生成新的莎士比亞式的文本。
四、總結
在神經網路中引入非線性是非常重要的,它能夠幫助我們在許多任務中獲得更好的表現。本文中,我們介紹了三種引入非線性的方法:使用激活函數、卷積神經網路和遞歸神經網路。但是,這只是一個開始。未來如何引入更多的非線性將成為一個非常有趣的問題。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/297391.html