終于把神經(jīng)網(wǎng)絡(luò)算法搞懂了!
大家好,我是小寒
今天給大家分享一個(gè)強(qiáng)大的算法模型,神經(jīng)網(wǎng)絡(luò)
神經(jīng)網(wǎng)絡(luò)(Neural Network)是一類旨在模仿人類大腦結(jié)構(gòu)和功能的計(jì)算模型。
它由一系列相互連接的節(jié)點(diǎn)(稱為“神經(jīng)元”)組成,這些節(jié)點(diǎn)按照一定的層級結(jié)構(gòu)組織,通常包括輸入層、隱藏層和輸出層。
圖片
基本結(jié)構(gòu)
- 輸入層(Input Layer)
輸入層接收來自外部的數(shù)據(jù),每個(gè)節(jié)點(diǎn)對應(yīng)一個(gè)輸入特征。 - 隱藏層(Hidden Layers)
隱藏層位于輸入層和輸出層之間。神經(jīng)網(wǎng)絡(luò)的復(fù)雜性通常來源于隱藏層的數(shù)量和每一層中神經(jīng)元的數(shù)量。
每個(gè)隱藏層中的節(jié)點(diǎn)通過加權(quán)連接接收來自上一層的輸入信號(hào),并通過激活函數(shù)進(jìn)行非線性變換。 - 輸出層(Output Layer)
輸出層的節(jié)點(diǎn)輸出最終的結(jié)果,這些結(jié)果可以是分類標(biāo)簽、回歸值等。
圖片
神經(jīng)元的工作原理
為了更好地理解神經(jīng)網(wǎng)絡(luò)的工作原理,我們首先放大單個(gè)節(jié)點(diǎn)(神經(jīng)元)。
每個(gè)神經(jīng)元接收來自前一層的輸入,執(zhí)行以下步驟。
案例分享
下面是一個(gè)使用 numpy 來從頭構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò)的示例代碼。
import numpy as np
import matplotlib.pyplot as plt
# sigmoidfunction
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# define the derivative of the sigmoid function
def sigmoid_derivative(x):
return x * (1 - x)
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size
# Weights and biases
self.W1 = np.random.randn(self.input_size, self.hidden_size) # Weights between input and hidden layer
self.b1 = np.ones((1, self.hidden_size)) # Biases for the hidden layer
self.W2 = np.random.randn(self.hidden_size, self.output_size) # Weights between hidden and output layer
self.b2 = np.ones((1, self.output_size)) # Biases for the output layer
# Forward Pass
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1 # Linear combination for hidden layer
self.a1 = sigmoid(self.z1) # Apply activation function to hidden layer
self.z2 = np.dot(self.a1, self.W2) + self.b2 # Linear combination for output layer
self.a2 = self.z2 # Output layer (no activation for regression)
return self.a2
def backward(self, X, y, output, learning_rate):
m = X.shape[0] # Number of training examples
# Error and delta calculations
self.error = y - output # Error at the output layer
self.delta_output = self.error # Delta for the output layer
self.error_hidden = np.dot(self.delta_output, self.W2.T) # Error at the hidden layer
self.delta_hidden = self.error_hidden * sigmoid_derivative(self.a1) # Delta for the hidden layer
# Gradient calculations
self.W2_grad = np.dot(self.a1.T, self.delta_output) / m
self.b2_grad = np.sum(self.delta_output, axis=0, keepdims=True) / m
self.W1_grad = np.dot(X.T, self.delta_hidden) / m
self.b1_grad = np.sum(self.delta_hidden, axis=0, keepdims=True) / m
# Update weights and biases
self.W2 += learning_rate * self.W2_grad
self.b2 += learning_rate * self.b2_grad
self.W1 += learning_rate * self.W1_grad
self.b1 += learning_rate * self.b1_grad
# create a networkobjekt
nn = NeuralNetwork(input_size=2, hidden_size=4, output_size=1)
# define data
# [size, age]
X = np.array([
[100, 5], [120, 10], [80, 15], [150, 2], [90, 20],
[110, 7], [95, 12], [130, 8], [140, 5], [75, 18],
[85, 14], [125, 6], [100, 10], [135, 4], [105, 9],
[115, 11], [140, 3], [80, 20], [90, 22], [120, 14]
])
# Price in thousand euros
y = np.array([
[200], [220], [170], [280], [160],
[210], [175], [225], [270], [155],
[185], [230], [195], [265], [175],
[215], [275], [165], [185], [225]
])
# normalize data
X_mean, X_std = X.mean(axis=0), X.std(axis=0)
y_mean, y_std = y.mean(), y.std()
X_normalized = (X - X_mean) / X_std
y_normalized = (y - y_mean) / y_std
# Training loop
epochs = 2000
learning_rate = 0.01
losses = []
for epoch in range(epochs):
# Forward pass
output = nn.forward(X_normalized)
# Backward pass
nn.backward(X_normalized, y_normalized, output, learning_rate)
# Calculate and print loss
mse = np.mean(np.square(y_normalized - output))
losses.append(mse)
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {mse}")
# Prediction function
def predict(size, age):
"""
Predicts the house price based on size and age.
Args:
size: Size of the house.
age: Age of the house.
Returns:
The predicted price in thousand euros.
"""
input_normalized = (np.array([[size, age]]) - X_mean) / X_std
output_normalized = nn.forward(input_normalized)
return output_normalized * y_std + y_mean
plt.plot(losses)
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Loss while training")
plt.show()
# Test Prediction
print("\nPredictions:")
print(f"House with 110 m2 and 7 years: {predict(110, 7)[0][0]:.2f} t€")
print(f"House with 85 m2 and 12 years: {predict(85, 12)[0][0]:.2f} t€")
神經(jīng)網(wǎng)絡(luò)的類型
1.前饋神經(jīng)網(wǎng)絡(luò)(FNN)
前饋神經(jīng)網(wǎng)絡(luò) (FNN) 是最簡單的人工神經(jīng)網(wǎng)絡(luò),其中信息只朝一個(gè)方向移動(dòng),即向前移動(dòng),從輸入節(jié)點(diǎn),經(jīng)過隱藏節(jié)點(diǎn)(如果有),最后到達(dá)輸出節(jié)點(diǎn)。
網(wǎng)絡(luò)中沒有循環(huán)或環(huán)路,因此是一種簡單的架構(gòu)。
圖片
工作原理
- 輸入層:
輸入特征(例如,圖像的像素值)被輸入到網(wǎng)絡(luò)中。 - 隱藏層
每個(gè)隱藏層由處理來自前一層的輸入的神經(jīng)元組成。
每個(gè)神經(jīng)元計(jì)算其輸入的加權(quán)和,添加偏差,并將結(jié)果傳遞給激活函數(shù)(例如 ReLU、sigmoid)。 - 輸出層
最后一層提供網(wǎng)絡(luò)的輸出(例如,分類中的類概率或回歸中的連續(xù)值)。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# Build a simple Feedforward Neural Network
model = Sequential([
Dense(64, activatinotallow='relu', input_shape=(10,)), # Hidden layer with 64 neurons
Dense(64, activatinotallow='relu'), # Another hidden layer
Dense(1, activatinotallow='sigmoid') # Output layer for binary classification
])
# Compile the model
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# Summary of the model
model.summary()
2.卷積神經(jīng)網(wǎng)絡(luò)(CNN)
卷積神經(jīng)網(wǎng)絡(luò) (CNN) 是一類深度神經(jīng)網(wǎng)絡(luò),專門用于處理結(jié)構(gòu)化網(wǎng)格狀數(shù)據(jù)(例如圖像)。
它們使用卷積層自動(dòng)且自適應(yīng)地從輸入數(shù)據(jù)中學(xué)習(xí)特征的空間層次結(jié)構(gòu)。
- 卷積層
將一組過濾器(核)應(yīng)用于輸入,這些過濾器在輸入數(shù)據(jù)上滑動(dòng)以生成特征圖。 - 池化層
降低特征圖的維數(shù),使得網(wǎng)絡(luò)的計(jì)算效率更高,并且對輸入中的小平移具有不變性。
工作原理
- 輸入層
CNN 的輸入通常是以像素值矩陣表示的圖像。
對于彩色圖像,這通常是 3D 矩陣(高度 × 寬度 × 通道)。 - 卷積層
CNN 的核心思想是卷積運(yùn)算,其中一個(gè)稱為過濾器或內(nèi)核的小矩陣在輸入圖像上滑動(dòng),并計(jì)算過濾器與其覆蓋的圖像塊之間的點(diǎn)積。
此操作生成特征圖。 - 池化層
池化層減少了特征圖的空間維度(高度和寬度),使計(jì)算更易于管理,并允許網(wǎng)絡(luò)專注于最重要的特征。
最常見的類型是最大池化,它從特征圖的每個(gè)塊中獲取最大值。 - 全連接層
經(jīng)過幾個(gè)卷積層和池化層之后,神經(jīng)網(wǎng)絡(luò)中的高級推理通過全連接層完成。 - 輸出層
輸出層使用特定的激活函數(shù)(對于分類任務(wù),通常是 Softmax)來產(chǎn)生最終預(yù)測。輸出是所有可能類別的概率分布。
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical
# Load dataset
(X_train, y_train), (X_test, y_test) = mnist.load_data()
X_train = X_train.reshape(X_train.shape[0], 28, 28, 1)
X_test = X_test.reshape(X_test.shape[0], 28, 28, 1)
X_train = X_train.astype('float32') / 255
X_test = X_test.astype('float32') / 255
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# Build the CNN model
model = Sequential([
Conv2D(32, kernel_size=(3, 3), activatinotallow='relu', input_shape=(28, 28, 1)),
MaxPooling2D(pool_size=(2, 2)),
Conv2D(64, (3, 3), activatinotallow='relu'),
MaxPooling2D(pool_size=(2, 2)),
Flatten(),
Dense(128, activatinotallow='relu'),
Dense(10, activatinotallow='softmax')
])
# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Train the model
model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=10, batch_size=200)
# Evaluate the model
score = model.evaluate(X_test, y_test)
print(f'Test accuracy: {score[1]*100:.2f}%')
3.循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)
循環(huán)神經(jīng)網(wǎng)絡(luò) (RNN) 是一類用于處理順序數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)。與標(biāo)準(zhǔn)神經(jīng)網(wǎng)絡(luò)不同,RNN 具有循環(huán),可讓其保留先前輸入的“記憶”,因此非常適合處理涉及序列的任務(wù)。
圖片
- LSTM(長短期記憶)
一種 RNN,可以通過維護(hù)隨每次輸入更新的記憶單元來學(xué)習(xí)長期依賴關(guān)系。LSTM 解決了標(biāo)準(zhǔn) RNN 的梯度消失問題。 - GRU(門控循環(huán)單元)
LSTM 的簡化版本,將遺忘門和輸入門組合成單個(gè)更新門。
GRU 計(jì)算效率高,性能通常與 LSTM 一樣好。
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
# Build an LSTM for time series prediction
model = Sequential([
LSTM(50, activatinotallow='relu', input_shape=(10, 1)), # LSTM layer
Dense(1) # Output layer
])
# Compile the model
model.compile(optimizer='adam', loss='mse')
# Summary of the model
model.summary()