Course materials Β· Introduction to Machine Learning

[Week 2] A History of Machine Learning: The Emergence of Machines That Learn Their Own Features πŸš€

English translation

Welcome to Week 2!

Last time, we learned the basic types of Machine Learning and 'linear models'.

Today, we will go one step further: > "Why has Deep Learning become mainstream in modern Machine Learning?"

Let us travel back in time to find the answer to this question.

Today's goal is to understand the key ideas that overcame the limitations of each era,

The goal is to gain a natural sense of why Deep Learning is needed.

⛰️ Module 1: 'Limitations' of Traditional Machine Learning

Then,

Could machines also learn useful features on their own from data?

This question is the starting point of Deep Learning.

# Import libraries
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_digits

# Hide unnecessary warnings
import warnings
warnings.filterwarnings(action='ignore')

# Load the digit images built into scikit-learn (0–9)
digits = load_digits()

# Filter for only the digits '1' and '7'
X = digits.data[(digits.target == 1) | (digits.target == 7)]
y = digits.target[(digits.target == 1) | (digits.target == 7)]
y[y == 1] = 0  # Assign digit 1 to class 0
y[y == 7] = 1  # Assign digit 7 to class 1

# Feature Engineering: A human defines two features directly.
# Feature 1: Sum of all image pixel values (brightness)
feature1 = X.sum(axis=1)
# Feature 2: Ratio of pixel sums in the top and bottom halves of the image
feature2 = X[:, :32].sum(axis=1) / (X[:, 32:].sum(axis=1) + 1e-6)

# Visualize the data using 2 human-designed features
plt.figure(figsize=(8, 6))
plt.scatter(feature1[y==0], feature2[y==0], label='Digit 1')
plt.scatter(feature1[y==1], feature2[y==1], label='Digit 7')
plt.title("Data Distribution By Heuristics")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.legend()
plt.show()
print("두 νŠΉμ§•μœΌλ‘œ μ–΄λŠμ •λ„ ꡬ뢄이 λ˜λŠ” 것 κ°™μ§€λ§Œ, κ²ΉμΉ˜λŠ” 뢀뢄이 λ§Žμ•„ λ³΄μž…λ‹ˆλ‹€.")
<Figure size 800x600 with 1 Axes>
μ‹€ν–‰ κ²°κ³Ό
두 νŠΉμ§•μœΌλ‘œ μ–΄λŠμ •λ„ ꡬ뢄이 λ˜λŠ” 것 κ°™μ§€λ§Œ, κ²ΉμΉ˜λŠ” 뢀뢄이 λ§Žμ•„ λ³΄μž…λ‹ˆλ‹€.
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

# Human-designed feature data
X_features = np.c_[feature1, feature2]

# Split into training/test data
(X_train, X_test,
 y_train, y_test) = train_test_split(X_features, y,
                                     test_size=0.3,
                                     random_state=42)

# Train a Logistic Regression model
model = LogisticRegression()
model.fit(X_train, y_train)

# Check the results
accuracy = model.score(X_test, y_test)
print(f"μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§•μ„ μ‚¬μš©ν•œ λͺ¨λΈμ˜ 정확도: {accuracy * 100:.2f}%")
print("\nλ‚˜μ˜μ§€ μ•Šμ€ μ„±λŠ₯μ΄μ§€λ§Œ, 더 쒋은 νŠΉμ§•μ„ 찾으면 μ„±λŠ₯이 μ–Όλ§ˆλ‚˜ 더 였λ₯ΌκΉŒμš”?")
print("\n이처럼 λͺ¨λΈμ˜ μ„±λŠ₯이 'μ‚¬λžŒμ˜ 직관(Heuristics)'에 μ˜μ‘΄ν•˜λŠ” 것이,")
print(f"그리고 κ·Έ ν•œκ³„κ°€ λšœλ ·ν•œ 것이, 전톡적인 λ¨Έμ‹ λŸ¬λ‹μ˜ ν•œκ³„μ˜€μŠ΅λ‹ˆλ‹€.")
μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§•μ„ μ‚¬μš©ν•œ λͺ¨λΈμ˜ 정확도: 58.72%

λ‚˜μ˜μ§€ μ•Šμ€ μ„±λŠ₯μ΄μ§€λ§Œ, 더 쒋은 νŠΉμ§•μ„ 찾으면 μ„±λŠ₯이 μ–Όλ§ˆλ‚˜ 더 였λ₯ΌκΉŒμš”?

이처럼 λͺ¨λΈμ˜ μ„±λŠ₯이 'μ‚¬λžŒμ˜ 직관(Heuristics)'에 μ˜μ‘΄ν•˜λŠ” 것이,
그리고 κ·Έ ν•œκ³„κ°€ λšœλ ·ν•œ 것이, 전톡적인 λ¨Έμ‹ λŸ¬λ‹μ˜ ν•œκ³„μ˜€μŠ΅λ‹ˆλ‹€.

❄️ Module 2: The Birth of Artificial Neural Networks and the First 'AI Winter'

# Generate XOR problem data
X_xor = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y_xor = np.array([0, 1, 1, 0]) # Output 1 for different inputs and 0 for identical inputs

# Visualize the XOR data
plt.figure(figsize=(8, 6))
plt.scatter(X_xor[:, 0], X_xor[:, 1], c=y_xor, cmap='coolwarm', s=200)
plt.title("XOR Problem: Can we find the line for classification?")
plt.xlabel("Input 1")
plt.ylabel("Input 2")
plt.grid(True)
plt.show()
print("μ–΄λ–€ λ°©ν–₯으둜 직선을 그어도, λΉ¨κ°„ 점과 νŒŒλž€ 점을 μ™„λ²½ν•˜κ²Œ λ‚˜λˆŒ 수 μ—†μŠ΅λ‹ˆλ‹€.")
<Figure size 800x600 with 1 Axes>
μ‹€ν–‰ κ²°κ³Ό
μ–΄λ–€ λ°©ν–₯으둜 직선을 그어도, λΉ¨κ°„ 점과 νŒŒλž€ 점을 μ™„λ²½ν•˜κ²Œ λ‚˜λˆŒ 수 μ—†μŠ΅λ‹ˆλ‹€.
# Attempt to solve XOR using the linear model (Logistic Regression) from Week 1
xor_model = LogisticRegression()
xor_model.fit(X_xor, y_xor)

# Check the results
accuracy = xor_model.score(X_xor, y_xor)
print(f"μ„ ν˜• λͺ¨λΈμ˜ XOR 문제 정확도: {accuracy * 100:.2f}%")
print("\nλͺ¨λΈμ΄ '찍기'와 λ‹€λ¦„μ—†λŠ” μ„±λŠ₯을 λ³΄μ—¬μ€λ‹ˆλ‹€. μ΄λŠ” μ„ ν˜• λͺ¨λΈμ˜ λͺ…λ°±ν•œ ν•œκ³„μž…λ‹ˆλ‹€.")
μ„ ν˜• λͺ¨λΈμ˜ XOR 문제 정확도: 50.00%

λͺ¨λΈμ΄ '찍기'와 λ‹€λ¦„μ—†λŠ” μ„±λŠ₯을 λ³΄μ—¬μ€λ‹ˆλ‹€. μ΄λŠ” μ„ ν˜• λͺ¨λΈμ˜ λͺ…λ°±ν•œ ν•œκ³„μž…λ‹ˆλ‹€.

πŸ”₯ Module 3: Ideas That Thawed the AI Winter

The AI winter lasted a long time, but a few researchers kept seeking solutions.

It finally became possible to train Deep Neural Networks.

from sklearn.neural_network import MLPClassifier

# Create an MLP model (2 hidden layers, with 4-4 neurons)
mlp_model = MLPClassifier(hidden_layer_sizes=(4,4,),
                          activation='relu', solver='adam',
                          random_state=42, max_iter=1000)

# Train the MLP on the XOR data
mlp_model.fit(X_xor, y_xor)

# Check the results
accuracy = mlp_model.score(X_xor, y_xor)
print(f"MLP λͺ¨λΈμ˜ XOR 문제 정확도: {accuracy * 100:.2f}%")
print("\nμ—¬λŸ¬ 개의 선을 μ‘°ν•©ν•˜λŠ” MLPλŠ” λΉ„μ„ ν˜•μ μΈ XOR 문제λ₯Ό μ™„λ²½ν•˜κ²Œ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€!")
MLP λͺ¨λΈμ˜ XOR 문제 정확도: 100.00%

μ—¬λŸ¬ 개의 선을 μ‘°ν•©ν•˜λŠ” MLPλŠ” λΉ„μ„ ν˜•μ μΈ XOR 문제λ₯Ό μ™„λ²½ν•˜κ²Œ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€!
# Visualize the decision boundary learned by the MLP
plt.figure(figsize=(8, 6))
xx, yy = np.meshgrid(np.linspace(-0.5, 1.5, 100),
                     np.linspace(-0.5, 1.5, 100))
Z = mlp_model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.contourf(xx, yy, Z, cmap='coolwarm', alpha=0.8) # Show the decision boundary with background colors
plt.scatter(X_xor[:, 0], X_xor[:, 1],
            c=y_xor, cmap='coolwarm',
            s=200, edgecolors='k')
plt.title("Classification by MLP")
plt.show()
print("MLPλŠ” 그림처럼 직선이 μ•„λ‹Œ, λ³΅μž‘ν•œ ν˜•νƒœμ˜ 경계선을 λ§Œλ“€μ–΄λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.")
<Figure size 800x600 with 1 Axes>
μ‹€ν–‰ κ²°κ³Ό
MLPλŠ” 그림처럼 직선이 μ•„λ‹Œ, λ³΅μž‘ν•œ ν˜•νƒœμ˜ 경계선을 λ§Œλ“€μ–΄λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

πŸ’₯ Module 4: The Big Bang of Deep Learning

Despite the invention of Backpropagation, > Deep Learning still could not solve real-world problems,

It did not become mainstream.

At the time, nobody knew why, but

Two main reasons were discovered later.

  1. Slow computers (CPU)
  2. Insufficient training data

The decisive event that brought all this to light occurred in 2012.

# Solve Module 1's digit '1' versus '7' problem using Deep Learning (MLP).
# This time, do not use the human-designed features (feature1, feature2).
# Use all 64 raw image pixel values (X) directly.
# The problem is simple enough that a CNN is unnecessary.

# Split into training/test data
(X_train_orig,
 X_test_orig,
 y_train_orig,
 y_test_orig) = train_test_split(X, y, test_size=0.3, random_state=42)

# Create a deeper MLP model
deep_model = MLPClassifier(hidden_layer_sizes=(100, 50),
                           random_state=42, max_iter=500)

# Train directly on raw pixel data
deep_model.fit(X_train_orig, y_train_orig)

# Check the results
accuracy = deep_model.score(X_test_orig, y_test_orig)
print("λͺ¨λ“ˆ 1μ—μ„œ μ‚¬μš©ν–ˆλ˜ 데이터와 λ™μΌν•œ λ°μ΄ν„°μž…λ‹ˆλ‹€.")
print(f"λͺ¨λ“ˆ 1μ—μ„œ μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§• 기반 λͺ¨λΈμ˜ 정확도: 58.72%")
print(f"λ”₯λŸ¬λ‹ λͺ¨λΈ(MLP)의 정확도: {accuracy * 100:.2f}%")
print("\n✨ κ²°κ³Ό: λ”₯λŸ¬λ‹ λͺ¨λΈμ€ 64개 ν”½μ…€μ˜ λ³΅μž‘ν•œ 관계 μ†μ—μ„œ '슀슀둜' 졜적의 νŠΉμ§•μ„ ν•™μŠ΅ν•˜μ—¬,")
print(f"μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§•λ³΄λ‹€ 더 높은 μ„±λŠ₯을 λ³΄μ—¬μ€λ‹ˆλ‹€!")
λͺ¨λ“ˆ 1μ—μ„œ μ‚¬μš©ν–ˆλ˜ 데이터와 λ™μΌν•œ λ°μ΄ν„°μž…λ‹ˆλ‹€.
λͺ¨λ“ˆ 1μ—μ„œ μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§• 기반 λͺ¨λΈμ˜ 정확도: 58.72%
λ”₯λŸ¬λ‹ λͺ¨λΈ(MLP)의 정확도: 100.00%

✨ κ²°κ³Ό: λ”₯λŸ¬λ‹ λͺ¨λΈμ€ 64개 ν”½μ…€μ˜ λ³΅μž‘ν•œ 관계 μ†μ—μ„œ '슀슀둜' 졜적의 νŠΉμ§•μ„ ν•™μŠ΅ν•˜μ—¬,
μ‚¬λžŒμ΄ λ§Œλ“  νŠΉμ§•λ³΄λ‹€ 더 높은 μ„±λŠ₯을 λ³΄μ—¬μ€λ‹ˆλ‹€!