소개: 신경망이란 무엇입니까?
Le 인공 신경망 이는 현대 딥러닝의 기초를 나타냅니다. 인간 두뇌의 구조에서 영감을 받은 이러한 컴퓨팅 아키텍처는 다음과 같은 기능을 제공합니다. 반복적인 최적화 프로세스를 통해 데이터로부터 복잡한 패턴을 학습합니다. 역전파. 이미지 분류부터 기계번역까지, 신경망은 세계에서 가장 진보된 인공 지능 애플리케이션을 구동합니다.
이 시리즈의 첫 번째 기사에서는 딥러닝과 신경망, 우리는 떠날 것이다 역사적 기원부터 퍼셉트론 (1958) 기본 개념에 도달하기 위해 네트워크가 학습할 수 있는 방법: 가중치, 편향, 활성화 함수, 경사하강법 그리고 역전파. 마지막으로 Python과 PyTorch를 사용하여 처음부터 신경망을 구현해 보겠습니다.
무엇을 배울 것인가
- 신경망의 역사: 퍼셉트론부터 현대 딥러닝까지
- 신경망 아키텍처: 입력, 은닉 및 출력 레이어
- 활성화 기능: ReLU, Sigmoid, Tanh 및 시각적 비교
- 역전파: 네트워크가 기울기를 계산하고 가중치를 업데이트하는 방법
- 손실 함수: 다양한 작업을 위한 MSE 및 교차 엔트로피
- NumPy 및 PyTorch의 실제 구현
퍼셉트론: 최초의 인공 뉴런
1958년 프랭크 로젠블라트(Frank Rosenblatt)는 퍼셉트론, 최초의 뉴런 모델 인공. 아이디어는 단순하지만 혁신적이었습니다. 수치 입력을 받는 계산 단위, 신을 곱해 가중치 (가중치), 결과를 더하고 이진 출력을 생성합니다. 임계값 함수를 통해.
퍼셉트론은 수학적으로 다음을 계산합니다.
# Percettrone semplice in Python
import numpy as np
class Perceptron:
def __init__(self, n_inputs, learning_rate=0.01):
self.weights = np.random.randn(n_inputs)
self.bias = 0.0
self.lr = learning_rate
def predict(self, x):
"""Forward pass: somma pesata + soglia"""
linear_output = np.dot(x, self.weights) + self.bias
return 1 if linear_output >= 0 else 0
def train(self, X, y, epochs=100):
"""Regola di apprendimento del percettrone"""
for _ in range(epochs):
for xi, yi in zip(X, y):
prediction = self.predict(xi)
error = yi - prediction
self.weights += self.lr * error * xi
self.bias += self.lr * error
# Esempio: AND gate
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1])
p = Perceptron(n_inputs=2)
p.train(X, y, epochs=50)
print([p.predict(xi) for xi in X]) # [0, 0, 0, 1]
퍼셉트론은 문제 해결에 효과적입니다. 선형 분리 가능 AND나 OR처럼 말이죠. 그러나 1969년에 민스키(Minsky)와 페퍼트(Papert)는 단일 퍼셉트론으로는 다음 문제를 해결할 수 없음을 입증했습니다. 문제 XOR, 여기서 클래스는 직선으로 분리될 수 없습니다. 이 발견 10년 이상 동안 신경망 연구 속도가 느려졌습니다. 는AI 겨울.
XOR 한계와 딥러닝의 필요성
XOR 문제는 그들이 필요하다는 것을 증명했습니다. 여러 레이어 (숨겨진 레이어) 해결 비선형 문제. 이러한 직관은 다음의 개발로 이어졌습니다. 다층 퍼셉트론(MLP) 그리고 수십 년 후에는 현대적인 딥 러닝으로 발전했습니다. 오늘날 우리는 단 하나의 숨겨진 레이어만 추가하는 것을 알고 있습니다. 비선형 활성화 함수인 신경망은 모든 연속 함수에 근접할 수 있습니다. (보편적 근사 정리).
신경망의 아키텍처: 레이어와 뉴런
신경망은 다음과 같이 구성됩니다. 레이어 (층) 상호 연결된 뉴런. 아키텍처 클래식에는 세 가지 유형의 레이어가 포함되어 있습니다.
- 입력 레이어: 원시 데이터를 수신합니다. 각 뉴런은 데이터 세트의 특징(예: 이미지의 픽셀, 텍스트의 단어)을 나타냅니다.
- 숨겨진 레이어: 처리가 이루어지는 하나 이상의 중간 레이어입니다. 각 뉴런은 이전 레이어로부터 입력을 받고 가중치와 편향을 적용한 후 활성화 함수를 통해 결과를 전달합니다.
- 출력 레이어: 최종 예측을 생성합니다. 이진 분류의 경우: 시그모이드가 있는 뉴런 1개. 다중 클래스의 경우: 소프트맥스가 있는 N개의 뉴런
Il 포워드 패스 데이터가 입력에서 출력으로 흘러가는 과정 모든 레이어. 각 뉴런에 대해 계산은 입력의 가중 합, 편향 추가의 세 단계를 따릅니다. 그리고 활성화 함수를 적용합니다.
활성화 함수: ReLU, Sigmoid 및 Tanh
Le 활성화 기능 네트워크에 비선형성을 도입하여 다음을 수행할 수 있습니다. 데이터의 복잡한 관계를 학습합니다. 그것들이 없으면 N개의 레이어로 구성된 네트워크는 다음과 같습니다. 깊이에 관계없이 단일 선형 레이어.
시그모이드
기능 시그모이드 (0, 1) 범위의 모든 값을 압축합니다. 역사적으로 오늘날 표준 활성화로 사용되며 주로 분류를 위한 출력 계층에서 사용됩니다. 바이너리. 그 주요 문제는 사라지는 그라데이션: 매우 높은 값의 경우 또는 매우 낮으면 기울기가 거의 0이 되어 학습 속도가 급격히 느려집니다.
Tanh
기능 tanh (하이퍼볼릭 탄젠트)는 (-1, 1) 범위의 값을 매핑합니다. 0을 중심으로 시그모이드보다 더 강한 기울기를 제공하므로 숨겨진 레이어에서 선호됩니다. 그러나 극단값에 대한 기울기 소실 문제도 발생합니다.
ReLU(정류 선형 장치)
ReLU 현대 딥러닝에서 가장 널리 사용되는 활성화 함수입니다. 그 공식은 매우 간단합니다: f(x) = max(0, x). 장점은 많습니다: 효율적인 계산, 양수 값에 대한 그라데이션이 사라지지 않고 희소 표현이 촉진됩니다. 유일한 사람 단점과 문제점 죽은 뉴런 (죽어가는 ReLU): 뉴런 수신 부정적인 입력은 항상 학습을 중단합니다.
import numpy as np
import matplotlib.pyplot as plt
# Implementazione delle funzioni di attivazione
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def tanh(x):
return np.tanh(x)
def relu(x):
return np.maximum(0, x)
def leaky_relu(x, alpha=0.01):
return np.where(x > 0, x, alpha * x)
# Derivate per backpropagation
def sigmoid_derivative(x):
s = sigmoid(x)
return s * (1 - s)
def relu_derivative(x):
return np.where(x > 0, 1, 0)
# Confronto visivo
x = np.linspace(-5, 5, 200)
fig, axes = plt.subplots(1, 4, figsize=(16, 4))
for ax, func, name in zip(axes, [sigmoid, tanh, relu, leaky_relu],
['Sigmoid', 'Tanh', 'ReLU', 'Leaky ReLU']):
ax.plot(x, func(x), linewidth=2)
ax.set_title(name)
ax.grid(True, alpha=0.3)
ax.axhline(y=0, color='k', linewidth=0.5)
ax.axvline(x=0, color='k', linewidth=0.5)
plt.tight_layout()
plt.savefig('activation_functions.png', dpi=150)
손실 함수: 측정 오류
La 손실 함수 (손실 함수)는 네트워크가 예측하는 정도를 정량화합니다. 실제 가치와 다르다. 훈련 중에 학습을 촉진하는 것은 오류 신호입니다.
MSE(평균 제곱 오차)
문제에 사용됨 회귀, MSE는 제곱의 평균을 계산합니다. 예측과 실제 값의 차이. 큰 오류에 더 많은 페널티를 적용하여 민감하게 만듭니다. 이상치에.
교차 엔트로피
문제의 경우 분류, 교차 엔트로피는 두 요소 사이의 거리를 측정합니다. 예측된 확률 분포와 실제 확률 분포. 이진 분류의 경우 이진 교차 엔트로피, 다중 클래스 la의 경우 범주형 교차엔트로피. 교차 엔트로피는 네트워크가 매우 안전하지만 잘못된 경우 더 강한 기울기를 생성하여 속도를 가속화합니다. 수정.
역전파: 네트워크가 학습하는 방법
La 역전파 (오류 역전파) 및 기본 알고리즘 신경망이 학습할 수 있게 해줍니다. 1986년 Rumelhart, Hinton 및 Williams가 발명한 적용하다 연쇄 법칙 기울기를 계산하는 미분 계산법 네트워크의 각 가중치에 대한 손실 함수.
프로세스는 4단계로 구분됩니다.
- 포워드 패스: 데이터는 입력에서 출력까지 네트워크를 통해 흐르며 각 계층의 활성화를 계산합니다.
- 손실 계산: 예측된 출력과 실제 값 사이의 오차를 측정합니다.
- 역방향 패스: 기울기는 출력에서 시작하여 입력을 향해 계산되어 오류를 거꾸로 전파합니다.
- 가중치 업데이트: 각 가중치는 학습률에 비례하여 기울기의 반대 방향으로 수정됩니다.
경사하강법: 기본 최적화 도구
Il 경사하강법 w = w - lr * dL/dw 공식에 따라 가중치를 업데이트합니다. 최신 변형에는 다음이 포함됩니다. 모멘텀이 있는 SGD (방향으로 속도를 높이세요. 그라데이션), 아담 (각 매개변수에 대한 적응형 학습률) e 아담 여 (올바른 체중 감소를 가진 Adam). Adam과 기본 최적화 프로그램 대부분의 딥러닝 애플리케이션에서
완전한 구현: PyTorch의 MLP
구현하여 모든 것을 하나로 묶어 보겠습니다. 다층 퍼셉트론 분류를 위해 PyTorch를 사용한 손글씨 숫자(MNIST 데이터세트):
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# Definizione del modello MLP
class MLP(nn.Module):
def __init__(self, input_size=784, hidden_sizes=[256, 128], num_classes=10):
super().__init__()
self.flatten = nn.Flatten()
self.network = nn.Sequential(
nn.Linear(input_size, hidden_sizes[0]),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(hidden_sizes[0], hidden_sizes[1]),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(hidden_sizes[1], num_classes)
)
def forward(self, x):
x = self.flatten(x)
return self.network(x)
# Setup dataset e dataloader
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
train_dataset = datasets.MNIST('./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST('./data', train=False, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)
# Training
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = MLP().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
for epoch in range(10):
model.train()
total_loss = 0
for batch_x, batch_y in train_loader:
batch_x, batch_y = batch_x.to(device), batch_y.to(device)
optimizer.zero_grad()
output = model(batch_x)
loss = criterion(output, batch_y)
loss.backward()
optimizer.step()
total_loss += loss.item()
# Valutazione
model.eval()
correct = 0
with torch.no_grad():
for batch_x, batch_y in test_loader:
batch_x, batch_y = batch_x.to(device), batch_y.to(device)
output = model(batch_x)
pred = output.argmax(dim=1)
correct += (pred == batch_y).sum().item()
accuracy = 100. * correct / len(test_dataset)
print(f'Epoch {epoch+1}: Loss={total_loss/len(train_loader):.4f}, '
f'Accuracy={accuracy:.2f}%')
이 모델은 대략적으로 도달합니다. 98% 정확도 10 에포크 이후 MNIST에서. 네트워크에는 두 개의 숨겨진 레이어(256 및 128 뉴런)는 ReLU를 활성화로 사용하고 Dropout을 정규화로 사용합니다. 학습률이 0.001인 Adam 최적화 프로그램.
딥러닝: 다중 계층이 작동하는 이유
Il 딥러닝 네트워크를 사용한다는 점에서 기존 머신러닝과 다릅니다. 많은 숨겨진 레이어가 있습니다. 그런데 깊이가 왜 그렇게 중요한가요?
대답은 기능의 계층적 구성. 각 레이어는 다음을 학습합니다. 증가하는 추상화 수준에서 패턴을 인식합니다.
- 레이어 1: 가장자리, 그라데이션 및 단순한 질감을 감지합니다.
- 레이어 2: 모서리를 기하학적 모양(모서리, 곡선)으로 결합합니다.
- 레이어 3: 사물의 일부(눈, 바퀴, 창문)를 인식합니다.
- 레이어 4+: 완전한 객체와 합성 장면 식별
이러한 표현 계층 구조로 인해 딥 네트워크가 다음과 같은 이유가 됩니다. 레스넷 (152개 레이어)은 이미지 분류에서 초인적인 성능을 달성할 수 있습니다. 단일 레이어는 결코 동일한 복잡성을 포착할 수 없습니다.
그러나 깊이에는 문제도 따릅니다. 사라지는 그라데이션 어렵게 만든다 오류 신호가 여러 계층을 통과하면서 감쇠되기 때문에 매우 깊은 네트워크를 훈련시킵니다. 최신 솔루션에는 다음이 포함됩니다. 연결 건너뛰기 (레스넷), 배치 정규화 보다 안정적인 기울기를 유지하는 ReLU와 같은 활성화 함수.
시리즈의 다음 단계
- 다음 기사에서는 CNN(컨벌루션 신경망), 컴퓨터 비전에 혁명을 일으킨 아키텍처
- 컨볼루션과 풀링을 통해 이미지에서 공간 특징을 추출하는 방법을 살펴보겠습니다.
- PyTorch에서 VGG 및 ResNet과 같은 클래식 아키텍처를 구현합니다.







