hong.com
Final
2025-08-06
2025-08-07
2025-08-08
2025-08-11
2025-08-12
2025-08-13
2025-08-14
2025-08-18
2025-08-19
Project
C Language
game instructions
FFT
game instructions
Study
C Language
ARM System Programming
C Programming - Challenges
C programming
Linux
Day1
Day2
Day3
Day4
Day5
Day6
Day7
Day8
SKIN_Project copy
SKIN_Project
perceptron
System Verilog
Day1
Day2
Day3
VLSI Circuits Design
Day1
Subsubcategory 1
Subsubcategory 2
example
Home
Contact
Copyright ยฉ 2024 |
Yankos
Home
>
Study
> Linux
๐ ๆ้ใขใค (โโขแดโขโ)โก โง*ใ
Linux
SKIN_Project
3์ผ๊ป๋ก ํ ๊น๋ Google Colab Dataset ๊ตฌ๊ธ ๋๋ผ์ด๋ธ > ๋ด ๋๋ผ์ด๋ธ > SKIN > dataset_skin Code : SKIN_Project.ipynb import matplotlib.pyplot as plt import numpy as np import os from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.applications import MobileNetV2 from tensorflow.keras import models, layers from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint # โ Google Drive ๋ง์ดํธ from google.colab import drive drive.mount('/content/drive') # โ ๊ฒฝ๋ก ์ค์ dataset_path = '/content/drive/MyDrive/SKIN/dataset_skin' # ๋๊ฐ ์ฌ๋ฆฐ ๊ฒฝ๋ก๋ก ์์ model_save_path = '/content/drive/MyDrive/SKIN/skin_model.h5' # ์ํ๋ ์ ์ฅ ๊ฒฝ๋ก # โ ๋ฐ์ดํฐ ์ฆ๊ฐ ์ค์ (rotation_range๋ 15๋๋ง ์ค) datagen = ImageDataGenerator( rescale=1./255, validation_split=0.2, rotation_range=15, width_shift_range=0.05, height_shift_range=0.05, shear_range=0.1, zoom_range=0.1, brightness_range=[0.8, 1.2], horizontal_flip=True, fill_mode='nearest' ) # โ ๋ฐ์ดํฐ ๋ก๋ฉ train_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), # MobileNetV2๋ ์ต์ 96x96๋ถํฐ ๊ฐ๋ฅ batch_size=32, class_mode='categorical', subset='training', shuffle=True ) val_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), batch_size=32, class_mode='categorical', subset='validation', shuffle=True ) # โ ํด๋์ค ์ด๋ฆ ์๋ ์ถ์ถ class_names = list(train_generator.class_indices.keys()) print("ํด๋์ค ์ธ๋ฑ์ค:", train_generator.class_indices) # โ MobileNetV2 ๊ธฐ๋ฐ ๋ชจ๋ธ ๊ตฌ์ฑ base_model = MobileNetV2(input_shape=(96, 96, 3), include_top=False, weights='imagenet') base_model.trainable = False model = models.Sequential([ base_model, layers.GlobalAveragePooling2D(), layers.Dense(128, activation='relu'), layers.Dropout(0.5), layers.Dense(len(class_names), activation='softmax') ]) model.compile(optimizer=Adam(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy']) # โ ์ฝ๋ฐฑ ์ค์ early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) checkpoint = ModelCheckpoint('best_model.h5', save_best_only=True) # โ ํ์ต ์คํ history = model.fit( train_generator, validation_data=val_generator, epochs=50, callbacks=[early_stop, checkpoint], verbose=2 ) # โ ๊ฒฐ๊ณผ ์๊ฐํ acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(acc)) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and Validation Accuracy') plt.legend() plt.show() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and Validation Loss') plt.legend() plt.show() # โ ํ์ต ์ด๋ฏธ์ง ์์ x_batch, y_batch = next(train_generator) plt.figure(figsize=(10, 10)) for i in range(25): plt.subplot(5, 5, i + 1) plt.xticks([]); plt.yticks([]); plt.grid(False) plt.imshow(x_batch[i]) label_idx = np.argmax(y_batch[i]) plt.xlabel(class_names[label_idx]) plt.tight_layout() plt.show() # โ ๋ชจ๋ธ ์ ์ฅ (.h5 ํ์ผ) model.save(model_save_path) print(f"๋ชจ๋ธ์ด ์ ์ฅ๋์์ต๋๋ค: {model_save_path}") Result Ubuntu Terminal # ์์ ํ ๋๋ ํ ๋ฆฌ ์์ฑ ํ ์ด๋ mkdir skin_project cd skin_project # ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ python3 -m venv venv source venv/bin/activate # ํ์ํ ํจํค์ง ์ค์น pip install tensorflow opencv-python numpy # skin_names.json ์์ฑ vi skin_names.json // skin_names.json [ "๊ธฐ์ ์ธํฌ์", "ํํผ๋ญ์ข ", "ํ๊ด์ข ", "๋น๋ฆฝ์ข ", "ํ์์ ", "ํธํ์ธํฌ์", "์ฌ๋ง๊ท" ] # NanumGothic ์ค์น sudo apt install fonts-nanum fc-list | grep NanumGothic # Pillow ํจํค์ง ์ค์น pip install Pillow # predict_cam.py ์์ฑ vi predict_cam.py # predict_cam.py import cv2 import numpy as np import tensorflow as tf import json from PIL import ImageFont, ImageDraw, Image # ํด๋์ค ์ด๋ฆ (ํ๊ธ) ๋ถ๋ฌ์ค๊ธฐ with open("skin_names.json", "r") as f: class_names = json.load(f) # ๋ชจ๋ธ ๋ก๋ model = tf.keras.models.load_model("skin_model.h5") # ํ๊ธ ํฐํธ ๊ฒฝ๋ก (Ubuntu์์ ์ฌ์ฉ ๊ฐ๋ฅ) FONT_PATH = "/usr/share/fonts/truetype/nanum/NanumGothic.ttf" font = ImageFont.truetype(FONT_PATH, 32) # ์น์บ ์์ cap = cv2.VideoCapture(2) print("Press 'q' to quit.") while True: ret, frame = cap.read() if not ret: break # ์์ธก์ ์ํ ์ ์ฒ๋ฆฌ img = cv2.resize(frame, (96, 96)) img_array = np.expand_dims(img / 255.0, axis=0) pred = model.predict(img_array)[0] label = class_names[np.argmax(pred)] confidence = np.max(pred) # ์๋ณธ ํ๋ ์์ Pillow ์ด๋ฏธ์ง๋ก ๋ณํ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(frame_rgb) draw = ImageDraw.Draw(pil_img) text = f"{label} ({confidence*100:.1f}%)" # ํ ์คํธ ์ถ๋ ฅ draw.text((10, 30), text, font=font, fill=(0, 255, 0)) # ์ด๋ก์ # ๋ค์ OpenCV ํ์์ผ๋ก ๋ณํํ์ฌ ์ถ๋ ฅ frame_bgr = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR) cv2.imshow("Skin Classifier", frame_bgr) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() cv2.destroyAllWindows() Comment ์น์บ ์ผ๋ก ์ธ์ํ ๊ฒฐ๊ณผ ํ์์ ์ ์ ๋๋ก ์ธ์ํ์ง ๋ชปํด์ ๋นผ์ผ๋ ๊ฒ ๊ฐ์ ๊ธฐ์ ์ธํฌ์ o ํํผ๋ญ์ข o ํ๊ด์ข o ๋น๋ฆฝ์ข o ํ์์ x ํธํ์ธํฌ์ o ์ฌ๋ง๊ท o
Study
ยท 2025-07-04
SKIN_Project
์ต์ข ํ๊ฑฐ ๋ ธ์ ์ ์ฒดํฌ Google Colab Dataset ๊ตฌ๊ธ ๋๋ผ์ด๋ธ > ๋ด ๋๋ผ์ด๋ธ > SKIN > dataset_skin Code : SKIN_Project.ipynb import matplotlib.pyplot as plt import numpy as np import os from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.applications import MobileNetV2 from tensorflow.keras import models, layers from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint # โ Google Drive ๋ง์ดํธ from google.colab import drive drive.mount('/content/drive') # โ ๊ฒฝ๋ก ์ค์ dataset_path = '/content/drive/MyDrive/SKIN/dataset_skin' # ๋๊ฐ ์ฌ๋ฆฐ ๊ฒฝ๋ก๋ก ์์ model_save_path = '/content/drive/MyDrive/SKIN/skin_model.h5' # ์ํ๋ ์ ์ฅ ๊ฒฝ๋ก # โ ๋ฐ์ดํฐ ์ฆ๊ฐ ์ค์ (rotation_range๋ 15๋๋ง ์ค) datagen = ImageDataGenerator( rescale=1./255, validation_split=0.2, rotation_range=15, width_shift_range=0.05, height_shift_range=0.05, shear_range=0.1, zoom_range=0.1, brightness_range=[0.8, 1.2], horizontal_flip=True, fill_mode='nearest' ) # โ ๋ฐ์ดํฐ ๋ก๋ฉ train_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), # MobileNetV2๋ ์ต์ 96x96๋ถํฐ ๊ฐ๋ฅ batch_size=32, class_mode='categorical', subset='training', shuffle=True ) val_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), batch_size=32, class_mode='categorical', subset='validation', shuffle=True ) # โ ํด๋์ค ์ด๋ฆ ์๋ ์ถ์ถ class_names = list(train_generator.class_indices.keys()) print("ํด๋์ค ์ธ๋ฑ์ค:", train_generator.class_indices) # โ MobileNetV2 ๊ธฐ๋ฐ ๋ชจ๋ธ ๊ตฌ์ฑ base_model = MobileNetV2(input_shape=(96, 96, 3), include_top=False, weights='imagenet') base_model.trainable = False model = models.Sequential([ base_model, layers.GlobalAveragePooling2D(), layers.Dense(128, activation='relu'), layers.Dropout(0.5), layers.Dense(len(class_names), activation='softmax') ]) model.compile(optimizer=Adam(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy']) # โ ์ฝ๋ฐฑ ์ค์ early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) checkpoint = ModelCheckpoint('best_model.h5', save_best_only=True) # โ ํ์ต ์คํ history = model.fit( train_generator, validation_data=val_generator, epochs=50, callbacks=[early_stop, checkpoint], verbose=2 ) # โ ๊ฒฐ๊ณผ ์๊ฐํ acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(acc)) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and Validation Accuracy') plt.legend() plt.show() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and Validation Loss') plt.legend() plt.show() # โ ํ์ต ์ด๋ฏธ์ง ์์ x_batch, y_batch = next(train_generator) plt.figure(figsize=(10, 10)) for i in range(25): plt.subplot(5, 5, i + 1) plt.xticks([]); plt.yticks([]); plt.grid(False) plt.imshow(x_batch[i]) label_idx = np.argmax(y_batch[i]) plt.xlabel(class_names[label_idx]) plt.tight_layout() plt.show() # โ ๋ชจ๋ธ ์ ์ฅ (.h5 ํ์ผ) model.save(model_save_path) print(f"๋ชจ๋ธ์ด ์ ์ฅ๋์์ต๋๋ค: {model_save_path}") Result Ubuntu Terminal # ์์ ํ ๋๋ ํ ๋ฆฌ ์์ฑ ํ ์ด๋ mkdir skin_project cd skin_project # ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ python3 -m venv venv source venv/bin/activate # ํ์ํ ํจํค์ง ์ค์น pip install tensorflow opencv-python numpy # skin_names.json ์์ฑ vi skin_names.json // skin_names.json [ "๊ธฐ์ ์ธํฌ์", "ํํผ๋ญ์ข ", "ํ๊ด์ข ", "๋น๋ฆฝ์ข ", "ํ์์ ", "ํธํ์ธํฌ์", "์ฌ๋ง๊ท" ] # NanumGothic ์ค์น sudo apt install fonts-nanum fc-list | grep NanumGothic # Pillow ํจํค์ง ์ค์น pip install Pillow # predict_cam.py ์์ฑ vi predict_cam.py # predict_cam.py import cv2 import numpy as np import tensorflow as tf import json from PIL import ImageFont, ImageDraw, Image # ํด๋์ค ์ด๋ฆ (ํ๊ธ) ๋ถ๋ฌ์ค๊ธฐ with open("skin_names.json", "r") as f: class_names = json.load(f) # ๋ชจ๋ธ ๋ก๋ model = tf.keras.models.load_model("skin_model.h5") # ํ๊ธ ํฐํธ ๊ฒฝ๋ก (Ubuntu์์ ์ฌ์ฉ ๊ฐ๋ฅ) FONT_PATH = "/usr/share/fonts/truetype/nanum/NanumGothic.ttf" font = ImageFont.truetype(FONT_PATH, 32) # ์น์บ ์์ cap = cv2.VideoCapture(2) print("Press 'q' to quit.") while True: ret, frame = cap.read() if not ret: break # ์์ธก์ ์ํ ์ ์ฒ๋ฆฌ img = cv2.resize(frame, (96, 96)) img_array = np.expand_dims(img / 255.0, axis=0) pred = model.predict(img_array)[0] label = class_names[np.argmax(pred)] confidence = np.max(pred) # ์๋ณธ ํ๋ ์์ Pillow ์ด๋ฏธ์ง๋ก ๋ณํ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) pil_img = Image.fromarray(frame_rgb) draw = ImageDraw.Draw(pil_img) text = f"{label} ({confidence*100:.1f}%)" # ํ ์คํธ ์ถ๋ ฅ draw.text((10, 30), text, font=font, fill=(0, 255, 0)) # ์ด๋ก์ # ๋ค์ OpenCV ํ์์ผ๋ก ๋ณํํ์ฌ ์ถ๋ ฅ frame_bgr = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR) cv2.imshow("Skin Classifier", frame_bgr) if cv2.waitKey(1) & 0xFF == ord("q"): break cap.release() cv2.destroyAllWindows() Comment ์น์บ ์ผ๋ก ์ธ์ํ ๊ฒฐ๊ณผ ํ์์ ์ ์ ๋๋ก ์ธ์ํ์ง ๋ชปํด์ ๋นผ์ผ๋ ๊ฒ ๊ฐ์ ๊ธฐ์ ์ธํฌ์ o ํํผ๋ญ์ข o ํ๊ด์ข o ๋น๋ฆฝ์ข o ํ์์ x ํธํ์ธํฌ์ o ์ฌ๋ง๊ท o
Study
ยท 2025-07-04
Day8 : Project_Plan
๐งฑ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ํ๊ฒฝ ๊ตฌ์ถ ctrl + alt + t โ ํฐ๋ฏธ๋ ์คํ ๋จ์ถํค htop โ ์ค์๊ฐ ์์คํ ๋ฆฌ์์ค(๋ฉ๋ชจ๋ฆฌ, CPU ์ฌ์ฉ๋ ๋ฑ) ํ์ธ ํด ์คํ sudo apt update โ ํจํค์ง ๋ชฉ๋ก ์ ๋ฐ์ดํธ (์ต์ ๋ฒ์ ํ์ธ์ฉ) sudo apt upgrade โ ์ค์น๋ ํจํค์ง๋ค์ ์ต์ ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋ sudo apt install ibus ibus-hangul โ ํ๊ธ ์ ๋ ฅ๊ธฐ(iBus + Hangul) ์ค์น sudo apt install fonts-nanum fonts-unfonts-core โ ๋๋๊ธ๊ผด, ์ค๊ธ๊ผด ๋ฑ ํ๊ธ ํฐํธ ์ค์น sudo update-alternatives --config x-www-browser โ ๊ธฐ๋ณธ ์น ๋ธ๋ผ์ฐ์ ์ค์ ๋ณ๊ฒฝ mkdir YOLO โ 'YOLO'๋ผ๋ ์ ํด๋ ์์ฑ cd YOLO/ โ YOLO ํด๋๋ก ์ด๋ python -m venv .yolo โ '.yolo'๋ผ๋ ์ด๋ฆ์ ๊ฐ์ํ๊ฒฝ(virtualenv) ์์ฑ source .yolo/bin/activate โ ๊ฐ์ํ๊ฒฝ ํ์ฑํ git clone https://github.com/ultralytics/yolov5 โ YOLOv5 ์ ์ฅ์๋ฅผ GitHub์์ ๋ณต์ cd yolov5/ โ ๋ณต์ ํ yolov5 ๋๋ ํ ๋ฆฌ๋ก ์ด๋ pip install -U pip โ pip(ํจํค์ง ๊ด๋ฆฌ์) ์ต์ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ pip install ultralytics โ Ultralytics ํจํค์ง ์ค์น (YOLOv5 ์คํ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํฌํจ) python detect.py --weights yolov5s.pt --source 0 --img 160 โ YOLOv5s ๋ชจ๋ธ๋ก ์น์บ (0๋ฒ)์ ์ค์๊ฐ ๊ฐ์ฒด ํ์ง (ํด์๋: 160) sudo apt install openssh-server โ SSH ์๋ฒ ์ค์น (๋ค๋ฅธ PC์์ ์๊ฒฉ ์ ์ ๊ฐ๋ฅํ๊ฒ ํจ) curl -fsSL https://ollama.com/install.sh | sh โ Ollama ์ค์น ์คํฌ๋ฆฝํธ ์คํ (๋ก์ปฌ AI ๋ชจ๋ธ ์คํ ๋๊ตฌ) ollama run gemma3:1b โ Gemma 3 1B ๋ชจ๋ธ ์คํ (๋ก์ปฌ LLM ํ ์คํธ) # PC์์ ์๊ฒฉ ์ ์ ssh hhhong@10.10.15.183 ๐ค ํ์๋ค๊ณผ ํ๋ก์ ํธ ๊ณํ ์๋ฆฝ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด๋ฅผ ํ์ฉํ On-Device AI ํ๋ก์ ํธ ๋ฐฉํฅ์ฑ ๋ ผ์ ๊น๋ฏผ๊ท: ์์ด ์ธ์ (Sign Language Recognition, SLR) ์์ฐฌํ: ๋จธ๋ฆฌ์นด๋ฝ ๋๊ป ๋ฐ ํ๋ชจ ์ด๊ธฐ ์ง๋จ + ๋ง์ถคํ ์๋ฐฉ ๊ด๋ฆฌ ๊ฐ์ด๋ ์์ฌํ: ๋ฅํ์ดํฌ ๊ฐ์ง ์์คํ ์์ฌํ: ๊ฑฐ์ง ๋ด์ค ํ๋ ์์คํ ๐ฌ ํ๊ณ ์ค์๊ฐ ๊ฐ์ฒด ํ์ง์ ๋ก์ปฌ AI ๋ชจ๋ธ์ด ๋์์ ๊ฐ๋ฅํจ์ ํ์ธํจ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ํ๊ฒฝ ์ธํ ์ค ํ๋ธ๋ฅผ ํตํด LAN ์ผ์ด๋ธ์ ๋ถํ ํ๋ ๊ณผ์ ์์ PC์์ ๋คํธ์ํฌ๋ฅผ ์ก์ง ๋ชปํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ผ๋, ์์ ์ข ๋ฃ ํ ์ ์์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด IP ์ถฉ๋ ๋ฌธ์ ์์์ ํ์ ํจ ๐ก ๊ฐ์ฌ๋์ ์กฐ์ธ โCNN ๋ชจ๋ธ์ C++ ์์ค์ผ๋ก ๋ฝ์ผ๋ฉด ๊ฐ์ฅ ์ข์.โ ํ๋ก์ ํธ ์ฑ๊ณต ์ฌ๋ถ์ ์๊ด์์ด, ๊ตฌํ ์์ค์ ๋์ด๋ ๊ฒ์ด ๋ ์ค์ํ๋ค๋ ์ทจ์ง์ ๋ง์ โ๏ธ ํด์ ๋ฐ ๋์ ์ดํด ๋จ์ํ ๋ชจ๋ธ์ โ๋๋ฆฌ๋ ๊ฒโ์ ๋์ด์, ๊ตฌ์กฐ๋ฅผ ์ ํํ ์ดํดํ๊ณ ์ง์ ๊ตฌํํด๋ณด๋ ๊ฒฝํ์ด ์ค์ํ๋ค๋ ๋ป PyTorch, TensorFlow ๊ฐ์ ํ๋ ์์ํฌ๋ฅผ ์ธ ์๋ ์์ง๋ง, ๊ธฐ์ด ์ํ/๋ก์ง์ ๋ฐํ์ผ๋ก CNN์ ์ง์ ๊ตฌํ(C++ ์์ค์ ์ ์์ค ์ ๊ทผ)ํด๋ณด๋ ๊ฒ์ด ์ค๋ ฅ ํฅ์์ ๋์๋จ ์ค๋ฌด ๋๋ ์จ๋๋ฐ์ด์ค ํ๊ฒฝ(Raspberry Pi ๋ฑ)์์๋ ์ต์ ํ๋ ์ ์์ค ์ฝ๋๋ก ๋ชจ๋ธ์ ์ด์ํ๋ ๋ฅ๋ ฅ๋ ์๊ตฌ๋จ ๐ ์์ผ๋ก์ ํ์ต ๋ฐฉํฅ์ ๋ฐ์ CNN ๋ ์ด์ด ๊ตฌ์ฑ ๋ฐ ์ฐ์ฐ ๋ฐฉ์(ReLU, Conv, Pooling ๋ฑ)์ ์ง์ ๊ตฌํํด๋ณด๋ ์ฐ์ต Python์ผ๋ก ๊ตฌํ โ ๊ฐ๋ฅํ๋ค๋ฉด C++๋ก ๊ตฌ์กฐ๋ง์ด๋ผ๋ ์ฎ๊ฒจ๋ณด๊ธฐ PyTorch์์ .model.eval()์ฒ๋ผ ๋ด๋ถ ๋์์ด ์ด๋ป๊ฒ ๊ตฌ์ฑ๋๋์ง ์ญ์ผ๋ก ์ดํด๋ณด๊ธฐ
Study
ยท 2025-07-02
Day7 : HARIBO_Mini_Project
๐ Model Improvement Strategy ๊ธฐ์กด CNN ๋ชจ๋ธ์ ๋ค์ ์ ๋ต์ ํตํฉํ์ฌ ์ฑ๋ฅ์ ํฅ์์ํจ ๊ตฌ์กฐ๋ฅผ ๊ตฌํํจ: ๋ฐ์ดํฐ ์ฆ๊ฐ ์ ์ฉ: ๋ค์ํ ์ด๋ฏธ์ง ๋ณํ์ ํตํด ํ์ต ๋ฐ์ดํฐ ๋ค์์ฑ ํ๋ณด ์ ์ดํ์ต ๋์ : MobileNetV2์ ์ฌ์ ํ์ต๋ ํน์ง ์ถ์ถ๊ธฐ ์ฌ์ฉ Dropout ๋ฐ Dense ๋ ์ด์ด ์ถ๊ฐ: ์ค๋ฒํผํ ๋ฐฉ์ง ๋ฐ ๋ชจ๋ธ ํํ๋ ฅ ํฅ์ EarlyStopping, ModelCheckpoint ์ ์ฉ: ๊ณผ์ ํฉ ๋ฐฉ์ง ๋ฐ ์ต์ ๋ชจ๋ธ ์ ์ฅ ๋ฐ์ดํฐ ์ฆ๊ฐ ๊ฐํ: ํ์ , ์ด๋, ํ๋/์ถ์, ๋ฐ์ ๋ฑ ๋ณตํฉ์ ์ฆ๊ฐ ์ ์ฉ ๐ฌ HARIBO_Dataset Preparation 5๊ฐ์ง ํ๋ฆฌ๋ณด ์ ค๋ฆฌ ์ข ๋ฅ(bear, cola, egg, heart, ring)๋ฅผ ์ง์ ์ดฌ์ํ์ฌ ์ด๋ฏธ์ง ๋ฐ์ดํฐ์ ์์ฑ ๋ค์ํ ๊ฐ๋ยท์กฐ๋ช ยท๋ฐฐ๊ฒฝ์์ ์์ง๋ ์ด๋ฏธ์ง ์ด 500์ฅ (๊ฐ ํด๋์ค๋น 100์ฅ ๋ด์ธ) ๊ตฌ๊ธ ๋๋ผ์ด๋ธ์ ์ ๋ก๋ ํ, Google Colab ํ๊ฒฝ์์ ์ค์ต์ฉ์ผ๋ก ์ฐ๋ ๐ก Code : CNN with Transfer Learning & Augmentation import matplotlib.pyplot as plt import numpy as np import os from tensorflow.keras.preprocessing.image import ImageDataGenerator from tensorflow.keras.applications import MobileNetV2 from tensorflow.keras import models, layers from tensorflow.keras.optimizers import RMSprop from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint # โ ๊ตฌ๊ธ ๋๋ผ์ด๋ธ ๋ง์ดํธ from google.colab import drive drive.mount('/content/drive') # โ ๊ฒฝ๋ก ์ค์ dataset_path = '/content/drive/MyDrive/haribo_dataset' model_save_path = '/content/drive/MyDrive/haribo_model.h5' # โ ๋ฐ์ดํฐ ์ฆ๊ฐ ์ค์ datagen = ImageDataGenerator( rescale=1./255, # ํฝ์ ๊ฐ์ 0~1 ๋ฒ์๋ก ์ ๊ทํ validation_split=0.2, # ์ ์ฒด ๋ฐ์ดํฐ ์ค 20%๋ฅผ ๊ฒ์ฆ์ฉ์ผ๋ก ์ฌ์ฉ rotation_range=90, # ์ต๋ ยฑ90๋ ๋ฒ์ ๋ด์์ ๋ฌด์์ ํ์ width_shift_range=0.1, # ์ ์ฒด ๋๋น์ 10%๋งํผ ์ข์ฐ ์ด๋ height_shift_range=0.1, # ์ ์ฒด ๋์ด์ 10%๋งํผ ์ํ ์ด๋ shear_range=0.1, # ์ ๋จ ๋ณํ (์ด๋ฏธ์ง๋ฅผ ๊ธฐ์ธ์ด๋ ํจ๊ณผ) zoom_range=0.1, # 10% ๋ฒ์ ๋ด ๋ฌด์์ ํ๋/์ถ์ horizontal_flip=True, # ์ด๋ฏธ์ง๋ฅผ ์ข์ฐ๋ก ๋ฌด์์ ๋ฐ์ fill_mode='nearest' # ๋ณํ ํ ์๊ธด ๋น ์์ญ์ ๊ฐ์ฅ ๊ฐ๊น์ด ํฝ์ ๋ก ์ฑ์ ) # โ ๋ฐ์ดํฐ ๋ก๋ฉ train_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), batch_size=32, class_mode='categorical', subset='training', shuffle=True ) val_generator = datagen.flow_from_directory( dataset_path, target_size=(96, 96), batch_size=32, class_mode='categorical', subset='validation', shuffle=True ) # โ ํด๋์ค ์ด๋ฆ ์๋ ์ถ์ถ class_names = list(train_generator.class_indices.keys()) print("ํด๋์ค ์ธ๋ฑ์ค:", train_generator.class_indices) # โ MobileNetV2 ๊ธฐ๋ฐ ๋ชจ๋ธ ๊ตฌ์ฑ base_model = MobileNetV2(input_shape=(96, 96, 3), include_top=False, weights='imagenet') base_model.trainable = False model = models.Sequential([ base_model, layers.GlobalAveragePooling2D(), layers.Dense(128, activation='relu'), layers.Dropout(0.5), layers.Dense(len(class_names), activation='softmax') # ํด๋์ค ์ ์๋ ๋ฐ์ ]) model.compile(optimizer=Adam(learning_rate=1e-4), loss='categorical_crossentropy', metrics=['accuracy']) # โ ์ฝ๋ฐฑ ์ค์ early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True) checkpoint = ModelCheckpoint('best_model.h5', save_best_only=True) # โ ํ์ต ์คํ history = model.fit( train_generator, validation_data=val_generator, epochs=50, callbacks=[early_stop, checkpoint], verbose=2 ) # โ ๊ฒฐ๊ณผ ์๊ฐํ acc = history.history['accuracy'] val_acc = history.history['val_accuracy'] loss = history.history['loss'] val_loss = history.history['val_loss'] epochs = range(len(acc)) plt.plot(epochs, acc, 'bo', label='Training acc') plt.plot(epochs, val_acc, 'b', label='Validation acc') plt.title('Training and Validation Accuracy') plt.legend() plt.show() plt.plot(epochs, loss, 'bo', label='Training loss') plt.plot(epochs, val_loss, 'b', label='Validation loss') plt.title('Training and Validation Loss') plt.legend() plt.show() # โ ํ์ต ์ด๋ฏธ์ง ์์ x_batch, y_batch = next(train_generator) plt.figure(figsize=(10, 10)) for i in range(25): plt.subplot(5, 5, i + 1) plt.xticks([]); plt.yticks([]); plt.grid(False) plt.imshow(x_batch[i]) label_idx = np.argmax(y_batch[i]) plt.xlabel(class_names[label_idx]) plt.tight_layout() plt.show() # โ ๋ชจ๋ธ ์ ์ฅ (.h5 ํ์ผ) model.save(model_save_path) print(f"๋ชจ๋ธ์ด ์ ์ฅ๋์์ต๋๋ค: {model_save_path}") โ Result : ํ์ต ๊ฒฐ๊ณผ ์๊ฐํ ๋ฐ ์์ธก ํ์ธ ๐ Summary MobileNetV2๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ์ ์ดํ์ต ๋ชจ๋ธ์ด ์ ์ ๋ฐ์ดํฐ์ ์์๋ ์ข์ ์ฑ๋ฅ์ ๋ณด์ ์ค์๊ฐ ์์ธก ํ๊ฒฝ์๋ ์ต์ ํ๋ ๋ชจ๋ธ ๊ตฌ์กฐ๋ก ์ ํ ๊ฐ๋ฅ (On-Device AI ์ ์ฉ ๊ฐ๋ฅ) ๐ป Real-Time Inference Setup on Terminal ๐ 1. ๋๋ ํ ๋ฆฌ ๊ตฌ์ฑ mkdir haribo_cam_classifier cd haribo_cam_classifier ๐ 2. ๊ฐ์ํ๊ฒฝ ์์ฑ ๋ฐ ํจํค์ง ์ค์น python3 -m venv venv source venv/bin/activate pip install tensorflow opencv-python-headless numpy ๐ฅ 3. ํ์ตํ ๋ชจ๋ธ(.h5)์ Google Drive์์ ๋ค์ด๋ก๋ํ์ฌ ๋ณต์ฌ haribo_model.h5 ํ์ผ์ Google Drive์์ ๋ค์ด๋ฐ์ haribo_cam_classifier ๋๋ ํ ๋ฆฌ์ ์์น์ํด ๐ผ๏ธ 4. ํด๋์ค ์ด๋ฆ ํ์ผ ์์ฑ (class_names.json) ["bear", "cola", "egg", "heart", "ring"] ๐ก 5. ์ค์๊ฐ ๋ถ๋ฅ ์ฝ๋ ์์ฑ (predict_cam.py) import cv2 import numpy as np import tensorflow as tf import json # ๋ชจ๋ธ๊ณผ ํด๋์ค ์ด๋ฆ ๋ก๋ model = tf.keras.models.load_model('haribo_model.h5') with open('class_names.json', 'r') as f: class_names = json.load(f) def preprocess(frame): img = cv2.resize(frame, (96, 96)) img = img.astype('float32') / 255.0 return np.expand_dims(img, axis=0) cap = cv2.VideoCapture(2) if not cap.isOpened(): print("์นด๋ฉ๋ผ๋ฅผ ์ด ์ ์์ต๋๋ค.") exit() print("์ ค๋ฆฌ ๋ถ๋ฅ ์์! (Q ํค๋ฅผ ๋๋ฅด๋ฉด ์ข ๋ฃ)") while True: ret, frame = cap.read() if not ret: break input_img = preprocess(frame) pred = model.predict(input_img) label = class_names[np.argmax(pred)] # ์์ธก ๊ฒฐ๊ณผ ํ๋ฉด์ ์ถ๋ ฅ cv2.putText(frame, f'Prediction: {label}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow('Haribo Classifier', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() ๐งฉ 6. OpenCV ์ค์น (GUI ์ง์ ํฌํจ) pip install opencv-python โถ๏ธ 7. ์ค์๊ฐ ์์ธก ์คํ python3 predict_cam.py โ 8. ๊ฒฐ๊ณผ ์ ๋ฆฌ ๐ฌ ๋ชจ๋ธ ์์ธก์ ์ํ 5๊ฐ ํด๋์ค ํ๋ฆฌ๋ณด ์ํ ์ ์ฒด ์ด๋ฏธ์ง ๐งช ์์ธก ์์: heart ๐งช ์์ธก ์์: ring ๐งช ์์ธก ์์: cola ๐งช ์์ธก ์์: egg ๐งช ์์ธก ์์: bear
Study
ยท 2025-07-01
Day6 : CNN
๐ CNN๋? CNN(Convolutional Neural Network)์ ์ด๋ฏธ์ง ์ธ์๊ณผ ๋ถ๋ฅ์ ํนํ๋ ์ธ๊ณต์ ๊ฒฝ๋ง์ผ๋ก, ์ฌ๋์ ์๊ฐ ์ฒ๋ฆฌ ๋ฐฉ์๊ณผ ์ ์ฌํ๊ฒ ๊ตญ์์ ์ธ ์์ญ์ ์ค์ฌ์ผ๋ก ํน์ง(feature)์ ์ถ์ถํ๊ณ ํ์ตํ๋ค. ๊ธฐ์กด์ MLP๋ณด๋ค ์ด๋ฏธ์ง ๊ตฌ์กฐ๋ฅผ ๋ ์ ๋ฐ์ํ๋ฉฐ, ์ปดํจํฐ ๋น์ (CV) ๋ถ์ผ์์ ๋๋ฆฌ ์ฌ์ฉ๋๋ค. <ํฉ์ฑ๊ณฑ ์ธต - Convolution Layer> ์ ๋ ฅ ์ด๋ฏธ์ง์ ํํฐ(์ปค๋)๋ฅผ ์ ์ฉํด ํน์ง ๋งต(Feature Map) ์์ฑ ๋ณดํต 3ร3 ํฌ๊ธฐ์ ํํฐ ์ฌ์ฉ (VGGNet ๋ฑ) โ ์์์๋ก ๋ค์ํ feature ์ถ์ถ ๊ฐ๋ฅ ํํฐ์ ๋๊ป๋ ์ ๋ ฅ ๋ฐ์ดํฐ(์: RGB โ 3)์ ์๋ ๋ง์ถฐ์ง Stride: ํํฐ ์ด๋ ๊ฐ๊ฒฉ, ์์์๋ก ์ ๋ฐํ๊ณ ํด์๋ก ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋จ Padding: ์ถ๋ ฅ feature map ํฌ๊ธฐ๋ฅผ ์ ์งํ๋ ค๋ฉด padding=same ์ค์ ํฉ์ฑ๊ณฑ ์ฐ์ฐ ๋ค์๋ ํ์ฑํ ํจ์(ReLU)๋ฅผ ์ ์ฉํด ๋น์ ํ์ฑ ๋์ <ํ๋ง ์ธต - Pooling Layer> MaxPooling: ํ๋ง ์์ญ์ ์ต๋๊ฐ โ ์ฃผ์ ํน์ง๋ง ๊ฐ์กฐ AveragePooling: ์์ญ ๋ด ํ๊ท ๊ฐ ์ฌ์ฉ GlobalAveragePooling: Flatten ์์ด ์ ์ฒด ํ๊ท ๋ง ๋ฝ์๋ด๋ ๋ฐฉ์ (GoogLeNet) ์ฐ์ฐ๋ ๊ฐ์ + ๊ณผ์ ํฉ ๋ฐฉ์ง + ๊ณต๊ฐ ๊ตฌ์กฐ ์์ฝ <๋ฐ์ง์ธต - Fully Connected Layer> Flatten ๋ ์ด์ด๋ก feature map์ 1์ฐจ์ ๋ฒกํฐ๋ก ๋ณํ ์ดํ Fully Connected Layer๋ฅผ ๊ฑฐ์ณ ํด๋์ค๋ณ ์ถ๋ ฅ๊ฐ ์์ฑ ์ฃผ๋ก softmax๋ฅผ ์ถ๋ ฅ์ธต ํ์ฑํ ํจ์๋ก ์ฌ์ฉํด ํ๋ฅ ๊ฐ ๋์ถ ๐งฎ example flow ์: ์ต์ข ์ถ๋ ฅ๊ฐ์ด (0.7, 0)์ด๊ณ ์ ๋ต์ด (1, 0)์ธ ๊ฒฝ์ฐ โ 0.3 ์ค์ฐจ ์ด ์ค์ฐจ๋ฅผ ์ญ์ ํ(backpropagation)๋ก ์ ํํ๋ฉฐ ๊ฐ์ค์น ์ ๋ฐ์ดํธ ๊ฒฝ์ฌํ๊ฐ๋ฒ(gradient descent) ๋ฑ ์ต์ ํ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉ ๐๏ธ CNN ๋ชจ๋ธ๊ณผ ์ธ๊ฐ ์๊ฐ ์ฒ๋ฆฌ์ ์ ์ฌ์ฑ ์ธ๊ฐ์ ์๊ฐ ํผ์ง๋ ๋จ์ํ ์๊ฐ ์ ๋ณด โ ๋ณต์กํ ํน์ง ์์ผ๋ก ์ฒ๋ฆฌ CNN๋ ์ธต์ด ๊น์ด์ง์๋ก ๋ณต์กํ feature๋ฅผ ์ถ์ถ ์ ์ฐจ์ edge โ ๊ณ ์ฐจ์ ํจํด ์ถ์ถ ํ๋ฆ์ด ์๊ฐ ์ ๋ณด ์ฒ๋ฆฌ์ ๋ฎ์ ๐ง ๋ํ CNN ๊ตฌ์กฐ๋ค AlexNet (2012): CNN์ ์ ๋ช ํ๊ฒ ๋ง๋ ์ต์ด์ ๊ตฌ์กฐ, 8์ธต ๊ตฌ์ฑ VGGNet (2014): 3ร3 ํํฐ ๋ฐ๋ณต ์ฌ์ฉ, ๊ตฌ์กฐ ๋จ์ & ํจ๊ณผ์ GoogLeNet: Inception ๊ตฌ์กฐ + Global Average Pooling ์ฌ์ฉ ResNet: Residual Block ์ฌ์ฉ โ ์ธต์ด ๊น์ด์ ธ๋ ์ฑ๋ฅ ์ ์ง ๐ ์ ์ดํ์ต (Transfer Learning) ๊ธฐ์กด ์ฌ์ ํ์ต๋ ๋ชจ๋ธ์ ๊ฐ์ค์น๋ฅผ ์ฌ์ฌ์ฉํ์ฌ ์ ์ ๋ฐ์ดํฐ๋ก๋ ํ์ต ๊ฐ๋ฅ Feature Extraction: ๊ธฐ์กด ๊ตฌ์กฐ ์ ์ง, ์ถ๋ ฅ์ธต๋ง ์๋ก ํ์ต Fine-Tuning: ์ผ๋ถ ์ธต์ ๊ณ ์ , ๋๋จธ์ง๋ ์ฌํ์ต ์ ์ ๋ฐ์ดํฐ ์ํฉ์์ ๊ฐ๋ ฅํ ์ฑ๋ฅ ๋ฐํ ๊ฐ๋ฅ ๐จโ๐ป ์ค์ต ๐ก Code : CNN Layer ๊ตฌํ import numpy as np from PIL import Image import matplotlib.pyplot as plt # ํฉ์ฑ๊ณฑ ํจ์ ๊ตฌํ def conv(a, b): c = np.array(a) * np.array(b) return np.sum(c) # MaxPooling ํจ์ ๊ตฌํ(ํ ๊ฐ์ map ๊ณ์ฐ) def MaxPooling(nimg): # 2d input nimg = np.array(nimg) i0, j0 = nimg.shape # i0 = nimg.shape[0], j0 = nimg.shape[1] i1 = int((i0 + 1) / 2) j1 = int((j0 + 1) / 2) output = np.zeros((i1, j1)) if i0 % 2 == 1: i0 += 1 tmp = np.zeros((1, j0)) nimg = np.concatenate([nimg, tmp], axis=0) if j0 % 2 == 1: j0 += 1 tmp = np.zeros((i0, 1)) nimg = np.concatenate([nimg, tmp], axis=1) for i in range(output.shape[0]): for j in range(output.shape[1]): a = np.array(nimg[2*i:2*i+2, 2*j:2*j+2]) output[i, j] = a.max() return output # ํฉ์ฑ๊ณฑ ์ถ๋ ฅ ์ธต(reature map) ํจ์ ๊ตฌํ(ํ ๊ฐ์ filter ๊ณ์ฐ) def featuring(nimg, filters): feature = np.zeros((nimg.shape[0] - 2, nimg.shape[1] - 2)) for i in range(feature.shape[0]): for j in range(feature.shape[1]): a = nimg[i:i+3, j:j+3] feature[i, j] = conv(a, filters) return feature # MaxPooling ์ถ๋ ฅ ์ธต ํจ์ ๊ตฌํ(์ฌ๋ฌ map ๊ณ์ฐ) def Pooling(nimg): nimg = np.array(nimg) pool0 = [] for i in range(len(nimg)): pool0.append(MaxPooling(nimg[i])) return pool0 # ๋ฐฐ์ด์ ๊ทธ๋ฆผ์ผ๋ก ๋ณํ def to_img(nimg): nimg = np.array(nimg) nimg = np.uint8(np.round(nimg)) fimg = [] for i in range(len(nimg)): fimg.append(Image.fromarray(nimg[i])) return fimg # feature map ์์ฑ(์ฌ๋ฌ filter ๊ณ์ฐ) def ConvD(nimg, filters): nimg = np.array(nimg) feat0 = [] for i in range(len(filters)): feat0.append(featuring(nimg, filters[i])) return feat0 # ReLU ํ์ฑํ ํจ์ def ReLU(fo): fo = np.array(fo) fo = (fo > 0) * fo return fo # CNN Layer ํจ์ : Conv + ReLU + MaxPooling def ConvMax(nimg, filters): nimg = np.array(nimg) f0 = ConvD(nimg, filters) f0 = ReLU(f0) fg = Pooling(f0) return f0, fg # ๊ทธ๋ฆผ ๊ทธ๋ฆฌ๊ธฐ : ํฉ์ฑ๊ณฑ ํ์ ์ํ์ MaxPooling ํ์ ์ํ๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ๊ทธ๋ฆฌ๊ธฐ def draw(f0, fg0, size=(12, 8), k=-1): # size์ k๋ ๊ธฐ๋ณธ๊ฐ ์ค์ plt.figure(figsize=size) for i in range(len(f0)): plt.subplot(2, len(f0), i + 1) plt.gca().set_title('Conv' + str(k) + '-' + str(i)) plt.imshow(f0[i]) for i in range(len(fg0)): plt.subplot(2, len(fg0), len(f0) + i + 1) plt.gca().set_title('MaxP' + str(k) + '-' + str(i)) plt.imshow(fg0[i]) if k != -1: # k=-1์ด ์๋๋ฉด ๊ทธ๋ฆผ์ ์ ์ฅ plt.savefig('conv' + str(k) + '.png') # 3๊ฐ์ activation map ํฉ์น๊ธฐ : MaxPooling ํ์ ๊ฒฐ๊ณผ map๋ค์ ํ๋์ ๋ฐ์ดํฐ๋ก ํตํฉ def join(mm): mm = np.array(mm) m1 = np.zeros((mm.shape[1], mm.shape[2], mm.shape[0])) for i in range(mm.shape[1]): for j in range(mm.shape[2]): for k in range(mm.shape[0]): m1[i][j][k] = mm[k][i][j] return m1 # CNN Layer ๊ณผ์ ์ ๊ณ์ฐํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๊ทธ๋ฆผ์ผ๋ก ์ถ๋ ฅ def ConvDraw(p0, filters, size=(12, 8), k=-1): f0, fg0 = ConvMax(p0, filters) f0_img = to_img(f0) fg1_img = to_img(fg0) draw(f0, fg0, size, k) p1 = join(fg0) return p1 # ํ ์คํธ ์คํ nimg31 = np.random.rand(10, 10) filters = [np.ones((3, 3))] * 3 m0 = ConvDraw(nimg31, filters, (12, 10), 0) โ Result : CNN Layer ๊ตฌํ ๐ ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ํ๊ฒฝ ๊ตฌ์ถ โ ์ค์น ๋ฐ ์ด๋ฏธ์ง ์ค์ sudo apt install rpi-imager : ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด ์ด๋ฏธ์ง ๋๊ตฌ ์ค์น rpi-imager : GUI ์คํ ํ OS ์ด๋ฏธ์ง ๋ค์ด๋ก๋ ๋ฐ ์ค์น ๊ฐ๋ฅ โ๏ธ ์ค์ ์ ๋ณด ์ด์์ฒด์ : Raspberry Pi OS (64-bit) ์ ์ฅ์: Mass Storage Device - 62.5 GB
Study
ยท 2025-06-30
Day5 : ์ ํ๋ชจ๋ธ, ์ ๊ฒฝ๋ง๋ชจ๋ธ
๐ ์ ํ ๋ชจ๋ธ ์์ฝ ๐ง 1. ์ ํ ๋ชจ๋ธ ๊ฐ์ ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๋ฒกํฐ ํํ๋ก ์ฒ๋ฆฌํ๋ ๊ฐ์ฅ ๋จ์ํ ํํ์ ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ์ ํ ๋ณํ + ๊ฐ๋จํ ๊ฒฐ์ ํจ์๋ก ๋ถ๋ฅ ์ํ ๐งฑ 2. ๋ฒกํฐํ (Vectorization) ์ ํ ๋ชจ๋ธ์ 1์ฐจ์ ๋ฒกํฐ ํํ์ ์ ๋ ฅ๋ง ์ฒ๋ฆฌ ๊ฐ๋ฅ ๋ฐ๋ผ์, 2D/3D ์ด๋ฏธ์ง๋ฅผ 1D ๋ฒกํฐ๋ก ๋ณํํด์ผ ํจ ์: 4x4 ํฝ์ ์ด๋ฏธ์ง๋ฅผ (1,16) ๋ฒกํฐ๋ก ๋ณํ ๐งฎ 3. ์ ํ ๋ถ๋ฅ๊ธฐ - Score ํจ์ ์ ๋ ฅ ๋ฒกํฐ์ ๊ฐ์ค์น ํ๋ ฌ์ ๊ณฑ์ผ๋ก ๊ฐ ํด๋์ค์ ์ ์(score) ๊ณ์ฐ Score ๊ณ์ฐ์ ํ๋ ฌ ๊ณฑ์ ํตํด ๋ณ๋ ฌ ์ฒ๋ฆฌ ๊ฐ๋ฅ ๐ 4. Softmax ๋ถ๋ฅ๊ธฐ ๊ฐ ํด๋์ค์ score๋ฅผ ํ๋ฅ ๊ฐ์ผ๋ก ๋ณํ softmax ์ถ๋ ฅ์ ๊ฐ ํด๋์ค์ ๋ํ ํ๋ฅ ๋ถํฌ๋ฅผ ๋ํ๋ ๐ 5. ์์ค ํจ์ - Cross Entropy Loss ์์ธก ํ๋ฅ ๊ณผ ์ ๋ต ํด๋์ค ๊ฐ์ ๊ฑฐ๋ฆฌ ๊ณ์ฐ ์ ๋ต ํด๋์ค์ ํด๋นํ๋ softmax ๊ฐ์ -log๋ฅผ ์ทจํด ์์ค ๊ณ์ฐ โ๏ธ 6. ์ต์ ํ - SGD (Stochastic Gradient Descent) ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ์ ํ์ตํ์ง ์๊ณ , ๋ฏธ๋ ๋ฐฐ์น ๋จ์๋ก ๊ฒฝ์ฌ ํ๊ฐ๋ฒ ์ ์ฉ ๊ณ์ฐ ํจ์จ์ฑ๊ณผ ๋น ๋ฅธ ์๋ ด์ ์ํด ์ฌ์ฉ๋จ ๐งช 7. ์ค์ต ๊ฐ์ (MNIST) MNIST ์ซ์ ์ด๋ฏธ์ง ๋ฐ์ดํฐ๋ฅผ ์ ํ ๋ชจ๋ธ์ ์ ์ฉํ์ฌ ํ์ต ์ ํ๋ ๋ฐ ์์ค ๊ณก์ ์ ์๊ฐํํ์ฌ ํ์ต ๊ฒฐ๊ณผ ๋ถ์ โ ์์ฝ ์ ํ ๋ชจ๋ธ์ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๋ถ๋ฅ๊ธฐ์ด๋ฉฐ, ๊ธฐ์ด ๊ฐ๋ (๋ฒกํฐํ, softmax, cross entropy, SGD ๋ฑ)์ ํ์ตํ๋ ๋ฐ ์ค์ํจ ์ดํ ์ ๊ฒฝ๋ง ๋ชจ๋ธ์ ์ดํดํ๊ธฐ ์ํ ๊ธฐ๋ฐ ์ง์์ ์ ๊ณตํจ ๐จโ๐ป ์ค์ต ๐ก Code : ๋ฒกํฐํ ์ฝ๋ ์ด๋ฏธ์ง๋ฅผ ๋ฒกํฐํํ ๋, numpy๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ flatten ๋๋ reshape์ ์ฌ์ฉํด ๋ฒกํฐํ ํ ์ ์๋ค. import numpy as np # random ํจ์๋ก 0~255 ์ฌ์ด์ ์์์ ์ ์๋ฅผ ์ฑ๋ถ์ผ๋ก ๊ฐ๋ 4x4 ํ๋ ฌ์ ๋ง๋ ๋ค. a = np.random.randint(0, 255, (4, 4)) a array([[ 38, 223, 157, 213], [104, 79, 231, 31], [117, 10, 48, 72], [128, 41, 6, 178]]) # flatten์ ์ฌ์ฉํด 1์ฐจ์ ํ๋ ฌ(๋ฒกํฐ)๋ก ๋ง๋ ๋ค. b = a.flatten() b array([ 38, 223, 157, 213, 104, 79, 231, 31, 117, 10, 48, 72, 128, 41, 6, 178]) # reshape๋ฅผ ์ฌ์ฉํด ํ๋ ฌ ํฌ๊ธฐ๋ฅผ ๋ฐ๊พผ๋ค. -1์ ์๋์ผ๋ก ๊ณ์ฐํ๋ค๋ ์๋ฏธ์ด๊ณ ์ด ๊ฒฝ์ฐ 16์ ์ ๋ ๊ฒ๊ณผ ๊ฐ๋ค. # ๋ง์ฝ (2, 8)์ ํ๋ ฌ๋ก ๋ฐ๊พธ๋ ค ํ๋ค๋ฉด reshape(2, -1) ๋๋ reshape(2, 8) ๋ ๋ค ๊ฐ์ ๊ฒฐ๊ณผ์ด๋ค. c = a.reshape(-1) c array([ 38, 223, 157, 213, 104, 79, 231, 31, 117, 10, 48, 72, 128, 41, 6, 178]) ๐ก Code : Mnist ์ค์ต # 1. ๊ธฐ๋ณธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ import numpy as np import pandas as pd # 2 ๋ฐ์ดํฐ์ ๋ถ๋ฌ์ค๊ธฐ from tensorflow.keras.datasets.mnist import load_data (train_x, train_y), (test_x, test_y) = load_data() # 2-1 ๋ฐ์ดํฐ ํ์ธํ๊ธฐ train_x.shape, train_y.shape # train ๋ฐ์ดํฐ ํฌ๊ธฐ ํ์ธ test_x.shape, test_y.shape # test ๋ฐ์ดํฐ ํฌ๊ธฐ ํ์ธ ((10000, 28, 28), (10000,)) # 2-2 ์ด๋ฏธ์ง ํ์ธํ๊ธฐ from PIL import Image img = train_x[0] import matplotlib.pyplot as plt img1 = Image.fromarray(img, mode='L') plt.imshow(img1) train_y[0] # ์ฒซ๋ฒ์งธ ๋ฐ์ดํฐ ํ์ธ np.uint8(5) # 3 ๋ฐ์ดํฐ ์ ์ฒ๋ฆฌ # 3-1 ์ ๋ ฅ ํํ ๋ณํ: 3์ฐจ์ โ 2์ฐจ์ # ๋ฐ์ดํฐ๋ฅผ 2์ฐจ์ ํํ๋ก ๋ณํ: ์ ๋ ฅ ๋ฐ์ดํฐ๊ฐ ์ ํ๋ชจ๋ธ์์๋ ๋ฒกํฐ ํํ train_x1 = train_x.reshape(60000, -1) test_x1 = test_x.reshape(10000, -1) # 3-2 ๋ฐ์ดํฐ ๊ฐ์ ํฌ๊ธฐ ์กฐ์ : 0~1 ์ฌ์ด ๊ฐ์ผ๋ก ๋ณํ train_x2 = train_x1 / 255 test_x2 = test_x1 / 255 # 4 ๋ชจ๋ธ ์ค์ # 4-1 ๋ชจ๋ธ ์ค์ ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ถ๋ฌ์ค๊ธฐ from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # 4-2 ๋ชจ๋ธ ์ค์ md = Sequential() md.add(Dense(10, activation='softmax', input_shape=(28*28,))) md.summary() # ๋ชจ๋ธ ์์ฝ /usr/local/lib/python3.11/dist-packages/keras/src/layers/core/dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs) Model: "sequential_6" โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโโโโโโโโโโโโโณโโโโโโโโโโโโโโโโ โ Layer (type) โ Output Shape โ Param # โ โกโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฉ โ dense_6 (Dense) โ (None, 10) โ 7,850 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโ Total params: 7,850 (30.66 KB) Trainable params: 7,850 (30.66 KB) Non-trainable params: 0 (0.00 B) # 5 ๋ชจ๋ธ ํ์ต ์งํ # 5-1 ๋ชจ๋ธ compile: ์์ค ํจ์, ์ต์ ํ ํจ์, ์ธก์ ํจ์ ์ค์ md.compile(loss = 'sparse_categorical_crossentropy', optimizer = 'sgd', metrics = ['acc']) # 5-2 ๋ชจ๋ธ ํ์ต: ํ์ต ํ์, batch_size, ๊ฒ์ฆ์ฉ ๋ฐ์ดํฐ ์ค์ hist = md.fit(train_x2, train_y, epochs=30, batch_size=64, validation_split=0.2) acc = hist.history['acc'] val_acc = hist.history['val_acc'] epoch = np.arange(1, len(acc) + 1) # ํ์ต๊ฒฐ๊ณผ ๋ถ์ : ํ์ต ๊ณก์ ๊ทธ๋ฆฌ๊ธฐ plt.figure(figsize=(10,8)) plt.plot(epoch, acc, 'b', label='Training accuracy') plt.plot(epoch, val_acc, 'r', label='Validation accuracy') plt.title('Training and validation accuracy') plt.xlabel('Epochs') plt.ylabel('Accuracy') plt.legend() plt.show() # 6 ํ ์คํธ์ฉ ๋ฐ์ดํฐ ํ๊ฐ md.evaluate(test_x2, test_y) # 7 ๊ฐ์ค์น ์ ์ฅ weight = md.get_weights() weight [array([[-0.01809908, 0.04423299, -0.00407743, ..., 0.06332525, -0.00251734, 0.00196751], [-0.050407 , -0.05998353, -0.07465094, ..., -0.01433843, 0.01071206, 0.03646336], [ 0.06986522, -0.0116923 , -0.07076468, ..., 0.02445704, -0.05563192, 0.0041509 ], ..., [ 0.03118712, -0.04921252, 0.00195412, ..., -0.00605295, -0.00202944, 0.07754893], [ 0.08052733, -0.0327304 , 0.02389491, ..., 0.00695625, 0.06758214, 0.03055982], [-0.05485652, 0.03522244, 0.03506895, ..., 0.00976416, -0.06175685, 0.04081956]], dtype=float32), array([-0.23029914, 0.30129498, 0.01726046, -0.17140533, 0.06494795, 0.772551 , -0.05629169, 0.3972938 , -0.94089097, -0.15446219], dtype=float32)] # Model Loss ์๊ฐํ plt.plot(hist.history['loss'], label='loss') plt.plot(hist.history['val_loss'], label='val_loss') plt.title('model loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['train', 'test'], loc='upper left') plt.show() CIFAR10 ์ค์ต 2025-06-27_2 ๋ณด๊ณ ์ ์ฐธ๊ณ
Study
ยท 2025-06-27
Day4 : Deep Learning
๐ง ๋ฅ๋ฌ๋ ๊ฐ์ ๋ฅ๋ฌ๋์ ์ธ๊ฐ์ ๋๋ฅผ ๋ชจ๋ฐฉํ ์ธ๊ณต์ ๊ฒฝ๋ง(ANN)์ ๊ธฐ๋ฐ์ผ๋ก ํ ๊ธฐ๊ณํ์ต ๊ธฐ์ ๋ก, ๋ค์ธต ๊ตฌ์กฐ์ ์ ๊ฒฝ๋ง์ ํตํด ๋ณต์กํ ํจํด์ ํ์ตํ๊ณ ์์ธกํ๋ ๋ฐ ์ฌ์ฉ๋๋ค. ๐ ์ธ๊ณต์ ๊ฒฝ๋ง(ANN)์ ๊ฐ๋ ์๋ฌผํ์ ๋ด๋ฐ ๊ตฌ์กฐ์์ ์ฐฉ์. ์ ๋ ฅ โ ๊ฐ์ค์น โ ํ์ฑํ ํจ์ โ ์ถ๋ ฅ ํ๋ฆ์ผ๋ก ๋์. ๊ฐ ์ ํธ์ ๊ฐ๋๋ ๊ฐ์ค์น(Weight)๋ก ํํ๋จ. ๐งฌ ๋ฅ๋ฌ๋(Deep Learning)์ด๋? ์๋์ธต์ด ์ฌ๋ฌ ๊ฐ์ธ ์ฌ์ธต ์ ๊ฒฝ๋ง(Deep Neural Network, DNN)์ ํตํด ํ์ตํ๋ ๋ฐฉ์. ์ฌ์ธต ํ์ต(Deep Learning)์ด๋ผ๊ณ ๋ ํจ. ๐ ๏ธ ์ ๊ฒฝ๋ง ๊ตฌ์ฑ ์์ ๊ตฌ์ฑ ์์ ์ค๋ช ์ ๋ ฅ์ธต ํ์ต ๋ฐ์ดํฐ๊ฐ ๋ค์ด์ค๋ ์ธต ์๋์ธต ๊ฐ์คํฉ ๊ณ์ฐ ๋ฐ ๋น์ ํ ๋ณํ ์ํ ์ถ๋ ฅ์ธต ์ต์ข ์์ธก๊ฐ์ ์ถ๋ ฅ ๊ฐ์ค์น ์ ๋ ฅ์ ์ค์๋๋ฅผ ๊ฒฐ์ ํธํฅ ๊ฐ์คํฉ์ ๋ํด์ง๋ ์์๋ก ์ถ๋ ฅ ์กฐ์ โ ๊ฐ์คํฉ (Weighted Sum) ๊ฐ ์ ๋ ฅ๊ฐ ร ๊ฐ์ค์น + ํธํฅ ์์: z = wโxโ + wโxโ + โฆ + b โ๏ธ ํ์ฑํ ํจ์ (Activation Function) ํจ์๋ช ํน์ง Sigmoid S์ ํํ, ์ถ๋ ฅ๊ฐ [0, 1], ๊ธฐ์ธ๊ธฐ ์์ค ๋ฌธ์ Tanh ์ถ๋ ฅ [-1, 1], ํ๊ท 0, sigmoid๋ณด๋ค ์ฐ์ ReLU 0 ์ดํ โ 0, 0 ์ด๊ณผ โ ๊ทธ๋๋ก ์ถ๋ ฅ, ๋น ๋ฅธ ํ์ต LeakyReLU ReLU์ ์์ ์ ๋ ฅ ๋ฌด๋ฐ์ ๋ฌธ์ ํด๊ฒฐ Softmax ํ๋ฅ ๋ถํฌ ์ถ๋ ฅ, ๋ค์ค ํด๋์ค ๋ถ๋ฅ์ ์ฌ์ฉ ๐งญ ํ์ต ๊ณผ์ (Training Flow) 1๏ธโฃ ์์ ํ (Forward Propagation) ์ ๋ ฅ โ ์๋์ธต โ ์ถ๋ ฅ์ธต์ผ๋ก ์์ธก๊ฐ ๋์ถ 2๏ธโฃ ์์ค ํจ์ (Loss Function) ์์ธก๊ฐ๊ณผ ์ค์ ๊ฐ์ ์ฐจ์ด๋ฅผ ๊ณ์ฐ ํ๊ท: MSE ๋ถ๋ฅ: Cross Entropy 3๏ธโฃ ์ตํฐ๋ง์ด์ (Optimizer) ๊ฒฝ์ฌํ๊ฐ๋ฒ ๊ธฐ๋ฐ์ผ๋ก ๊ฐ์ค์น ์ต์ ํ ์ ์ฒด/๋ฏธ๋ ๋ฐฐ์น ๋ฐฉ์ ์ฌ์ฉ 4๏ธโฃ ์ญ์ ํ (Backpropagation) ์ค์ฐจ๋ฅผ ์ญ๋ฐฉํฅ ์ ํํด ๊ฐ์ค์น ์ ๋ฐ์ดํธ ๊ฐ ์ธต์ ๊ฐ์ค์น์ ๋ํด ๋ฏธ๋ถ๊ฐ ๊ธฐ๋ฐ ๋ณด์ ๐งฑ ๋ฅ๋ฌ๋ ๋ชจ๋ธ์ ์ ํ ์ ํ ์ค๋ช DFN (์๋ฐฉํฅ ์ ๊ฒฝ๋ง) ๊ธฐ๋ณธ ๊ตฌ์กฐ, ๊ณ ์ ์ ๋ ฅ ์ฒ๋ฆฌ RNN (์ํ ์ ๊ฒฝ๋ง) ์๊ณ์ด ๋ฐ์ดํฐ ์ฒ๋ฆฌ, ๊ณผ๊ฑฐ ์ ๋ณด ๋ฐ์ LSTM RNN ๊ฐ์ , ์ฅ๊ธฐ ๊ธฐ์ต ์ ์ง CNN ์ด๋ฏธ์ง ๋ถ์ ํนํ, ํฉ์ฑ๊ณฑ ๋ฐ ํ๋ง ํ์ฉ ๐ง CNN์ ๊ตฌ์กฐ ํฉ์ฑ๊ณฑ์ธต: ํํฐ๋ฅผ ํตํด ํน์ง ์ถ์ถ ํ๋ง์ธต: ๋ฐ์ดํฐ ํฌ๊ธฐ ์ถ์, ํต์ฌ ์ ๋ณด ๋ณด์กด ์์ ์ฐ๊ฒฐ์ธต: ์ต์ข ๋ถ๋ฅ ์ํ ๐ ๋น๊ต ์์ฝ (DFN vs RNN vs CNN) ํญ๋ชฉ DFN RNN CNN ์ ๋ ฅ ์ ์ ์๊ณ์ด ์ด๋ฏธ์ง/์๊ณ์ด ํน์ง ๋จ๋ฐฉํฅ ์ํ ์ฐ๊ฒฐ ์ง์ญ์ ํน์ง ํ์ต ์ฌ์ ์ด๋ ค์ ์ค๊ฐ ํจ์จ ๋ฎ์ ๋ฎ์ ๋์ ๐ฌ ์๋ ์๋ฒ ๋ฉ (Word Embedding) ๋ฐฉ์ ์ค๋ช One-hot Encoding ํฌ์ ๋ฒกํฐ, ๋จ์ ๊ตฌ์กฐ Word2Vec ์ฃผ๋ณ ๋ฌธ๋งฅ โ ์ค์ฌ ๋จ์ด ์์ธก (CBOW/Skip-gram) TF-IDF ๋จ์ด ์ค์๋ ๊ฐ์ค์น ๋ถ์ฌ FastText ๋ถ๋ถ ๋จ์ด ๊ธฐ๋ฐ, OOV ๋ฌธ์ ํด๊ฒฐ GloVe ๋จ์ด ๋์ ๋ฑ์ฅ ํต๊ณ ๊ธฐ๋ฐ ELMo ๋ฌธ๋งฅ์ ๋ฐ๋ผ ๋ฒกํฐ๊ฐ ๋ฌ๋ผ์ง๋ ๋์ ์๋ฒ ๋ฉ ๐จ ์ ๋์ ์์ฑ ์ ๊ฒฝ๋ง (GAN) ๋ ๋คํธ์ํฌ๊ฐ ๊ฒฝ์: Generator: ์ง์ง ๊ฐ์ ๊ฐ์ง ๋ฐ์ดํฐ ์์ฑ Discriminator: ์ง์ง์ ๊ฐ์ง ๊ตฌ๋ณ ์์ , ์ด๋ฏธ์ง ์์ฑ ๋ฑ์์ ๊ฐ๋ ฅํ ์ฑ๋ฅ โ ์์ฝ ๋ฅ๋ฌ๋์ ์ธ๊ณต์ ๊ฒฝ๋ง์ ํ์ฅํ ๊ตฌ์กฐ๋ก, ๋ค์ํ ๋ฌธ์ ํด๊ฒฐ์ ์ ์ฉ ๊ฐ๋ฅ ํ์ฑํ ํจ์, ํ์ต ์๊ณ ๋ฆฌ์ฆ, ๋ชจ๋ธ ๊ตฌ์กฐ์ ๋ฐ๋ผ ์ฑ๋ฅ์ด ์ข์ฐ๋จ CNN, RNN, GAN, Word Embedding ๋ฑ์ ์ค์ ๋ฌธ์ ์ ๋ง๋ ๋ฅ๋ฌ๋ ๊ธฐ๋ฒ ์ ํ์ ๊ธฐ์ค์ด ๋๋ค. ๐ ๏ธ ์์ ํ ๋๋ ํ ๋ฆฌ ์์ฑ ๋ฐ ํ๊ฒฝ ์ค์ # 1. ์์ ๋๋ ํ ๋ฆฌ ์์ฑ mkdir F_MNIST # ๋๋ ํ ๋ฆฌ ์ด๋ฆ: F_MNIST cd F_MNIST # ํด๋น ๋๋ ํ ๋ฆฌ๋ก ์ด๋ # 2. ๊ฐ์ ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ python3 -m venv .fmnist # ๊ฐ์ ํ๊ฒฝ ์์ฑ (ํด๋ ์ด๋ฆ: .fmnist) source .fmnist/bin/activate # ๊ฐ์ ํ๊ฒฝ ํ์ฑํ # 3. ํจํค์ง ์ค์น pip install -U pip # pip ์ต์ ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋ pip install tensorflow # TensorFlow (๋ฅ๋ฌ๋ ํ๋ ์์ํฌ) pip install matplotlib # Matplotlib (์๊ฐํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ) pip install PyQt5 # PyQt5 (Matplotlib GUI ๋ฐฑ์๋์ฉ) pip install scikit_learn # scikit-learn (๋จธ์ ๋ฌ๋ ๋ฐ ํ๊ฐ ๋๊ตฌ) # 4. Qt GUI ๋ฐฑ์๋ ์ค์ (Wayland ํ๊ฒฝ์์ ํ์) export QT_QPA_PLATFORM=wayland # Qt GUI๋ฅผ Wayland์์ ์ ์ ๋์ํ๊ฒ ์ค์ ๐จโ๐ป ์ค์ต ๐ก Code : Fashion MNIST import tensorflow as tf from tensorflow import keras import numpy as np import matplotlib import matplotlib.pyplot as plt # dataset load fashion_mnist = keras.datasets.fashion_mnist # spilt data (train / test) (train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data() print(train_images.shape) print(train_labels.shape) print(test_images.shape) print(test_labels.shape) class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] matplotlib.use('Qt5Agg') NUM=20 plt.figure(figsize=(15,15)) plt.subplots_adjust(hspace=1) for idx in range(NUM): sp = plt.subplot(5,5,idx+1) plt.imshow(train_images[idx]) plt.title(f'{class_names[train_labels[idx]]}') plt.show() plt.figure() plt.imshow(train_images[0]) plt.colorbar() plt.grid(False) plt.show() # ๊ฐ๋จํ ์ด๋ฏธ์ง ์ ์ฒ๋ฆฌ (for ANN) train_images = train_images / 255.0 test_images = test_images / 255.0 class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] plt.figure(figsize=(10,8)) for i in range(20): plt.subplot(4,5,i+1) plt.xticks([]) plt.yticks([]) plt.grid(False) plt.imshow(train_images[i], cmap=plt.cm.binary) plt.xlabel(class_names[train_labels[i]]) plt.show() model = keras.Sequential ([ keras.layers.Flatten(input_shape=(28,28)), keras.layers.Dense(128, activation='relu'), keras.layers.Dense(10, activation='softmax'), ]) model.summary() model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) model.fit(train_images, train_labels, epochs=20) predictions = model.predict(test_images) predictions[0] np.argmax(predictions[0]) test_labels[0] def plot_image(i, predictions_array, true_label, img): predictions_array, true_label, img = predictions_array[i], true_label[i], img[i] plt.grid(False) plt.xticks([]) plt.yticks([]) plt.imshow(img, cmap=plt.cm.binary) predicted_label = np.argmax(predictions_array) if predicted_label == true_label: color = 'blue' else: color = 'red' plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label], 100*np.max(predictions_array), class_names[true_label]), color=color) def plot_value_array(i, predictions_array, true_label): predictions_array, true_label = predictions_array[i], true_label[i] plt.grid(False) plt.xticks([]) plt.yticks([]) thisplot = plt.bar(range(10), predictions_array, color="#777777") plt.ylim([0, 1]) predicted_label = np.argmax(predictions_array) thisplot[predicted_label].set_color('red') thisplot[true_label].set_color('blue') num_rows = 5 num_cols = 3 num_images = num_rows*num_cols plt.figure(figsize=(2*2*num_cols, 2*num_rows)) for i in range(num_images): plt.subplot(num_rows, 2*num_cols, 2*i+1) plot_image(i, predictions, test_labels, test_images) plt.subplot(num_rows, 2*num_cols, 2*i+2) plot_value_array(i, predictions, test_labels) plt.show() from sklearn.metrics import accuracy_score print('accuracy score : ', accuracy_score(tf.math.argmax(predictions, -1), test_labels))
Study
ยท 2025-06-26
Day3 : Perceptron
Report : Perceptron 1. ํผ์ ํธ๋ก ์ด๋? ์๋ฌผํ์ ๋ด๋ฐ์ ๋ชจ๋ฐฉํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ธ๊ณต์ ๊ฒฝ๋ง ์ ๋ ฅ ๊ฐ ร ๊ฐ์ค์น + ๋ฐ์ด์ด์ค๋ฅผ ํตํด ์ ํ๊ฒฐํฉ์ ๋ง๋ค๊ณ , ๋จ์ ๊ณ๋จ ํจ์(step function) ๋ก 0 ๋๋ 1์ ์ถ๋ ฅ ๊ฐ๋จํ ๊ตฌ์กฐ์ง๋ง, ์ ํ ๋ถ๋ฆฌ ๊ฐ๋ฅํ ๋ฌธ์ ๋ ์๋ฒฝํ๊ฒ ํด๊ฒฐํ ์ ์์ ํ๋์ ์ง์ ์ผ๋ก ๋๋ ์ ์์ผ๋ฉด โ ์ ํ ๋ถ๋ฆฌ ๊ฐ๋ฅ ๋จ์ ๊ณ์ฐ ํจ์ : ์ ๋ ฅ๊ฐ์ด 0๋ณด๋ค ํฌ๋ฉด 1์ ์ถ๋ ฅํ๊ณ , ๊ทธ ์ธ์ 0์ ์ถ๋ ฅํ๋ ํจ์ 2. ํผ์ ํธ๋ก ํ์ต ๋ฐฉ์ (์ฝ๋ ์ค์ฌ) # AND & OR & NAND & XOR Gate Perceptron import numpy as np import matplotlib.pyplot as plt class Perceptron: def __init__(self, input_size, lr=0.1, epochs=10): self.weights = np.zeros(input_size) self.bias = 0 self.lr = lr self.epochs = epochs self.errors = [] def activation(self, x): return np.where(x > 0, 1, 0) def predict(self, x): linear_output = np.dot(x, self.weights) + self.bias return self.activation(linear_output) def train(self, X, y): for epoch in range(self.epochs): total_error = 0 for xi, target in zip(X, y): prediction = self.predict(xi) update = self.lr * (target - prediction) self.weights += update * xi self.bias += update total_error += int(update != 0.0) self.errors.append(total_error) print(f"Epoch {epoch+1}/{self.epochs}, Errors: {total_error}") # AND ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_and = np.array([[0,0],[0,1],[1,0],[1,1]]) y_and = np.array([0,0,0,1]) print(" AND Gate Training") ppn_and = Perceptron(input_size=2) ppn_and.train(X_and, y_and) print("\n AND Gate Test:") for x in X_and: print(f"Input: {x}, Predicted Output: {ppn_and.predict(x)}") # OR ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_or = np.array([[0,0],[0,1],[1,0],[1,1]]) y_or = np.array([0,1,1,1]) print("\n OR Gate Training") ppn_or = Perceptron(input_size=2) ppn_or.train(X_or, y_or) print("\n OR Gate Test:") for x in X_or: print(f"Input: {x}, Predicted Output: {ppn_or.predict(x)}") # NAND ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_nand = np.array([[0,0],[0,1],[1,0],[1,1]]) y_nand = np.array([1,1,1,0]) # AND์ ๋ฐ๋ print("\n NAND Gate Training") ppn_nand = Perceptron(input_size=2) ppn_nand.train(X_nand, y_nand) print("\n NAND Gate Test:") for x in X_nand: print(f"Input: {x}, Predicted Output: {ppn_nand.predict(x)}") # XOR ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_xor = np.array([[0,0],[0,1],[1,0],[1,1]]) y_xor = np.array([0,1,1,0]) # ์ ํ ๋ถ๋ฆฌ ๋ถ๊ฐ๋ฅ print("\n XOR Gate Training") ppn_xor = Perceptron(input_size=2) ppn_xor.train(X_xor, y_xor) print("\n XOR Gate Test:") for x in X_xor: print(f"Input: {x}, Predicted Output: {ppn_xor.predict(x)}") 2-1. train() ํจ์ ํธ์ถ ppn_and.train(X_and, y_and) X_and: ์ ๋ ฅ ๋ฐ์ดํฐ ๋ฐฐ์ด (์: [0,0], [1,1] ๋ฑ) y_and: ๊ฐ ์ ๋ ฅ์ ๋ํ ์ ๋ต ์ถ๋ ฅ๊ฐ 2-2. ์ ์ฒด ๋ฐ๋ณต (epoch) ์์ for epoch in range(self.epochs): # ์ด 10๋ฒ ๋ฐ๋ณต ํ epoch๋ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ํ ๋ฒ ํ์ตํ๋ ์ฃผ๊ธฐ ์ด 10๋ฒ ๋ฐ๋ณตํ๋ฉด์ ์กฐ๊ธ์ฉ ๊ฐ์ค์น๋ฅผ ์กฐ์ 2-3. ํ epoch ๋ด ์ํ ๋ฐ๋ณต for xi, target in zip(X, y): ๊ฐ ๋ฐ์ดํฐ xi์ ์ ๋ต target์ ํ๋์ฉ ๊บผ๋ด ์์ฐจ ํ์ต 2-4. ์์ธก ๊ณผ์ prediction = self.predict(xi) predict() ๋ด๋ถ์์ ๋ค์ ์์๋ก ์๋: linear_output = wยทx + b activation() โ 0 ๋๋ 1 ๋ฐํ 2-5. ์ค์ฐจ ๊ณ์ฐ ๋ฐ ๊ฐ์ค์น/๋ฐ์ด์ด์ค ์ ๋ฐ์ดํธ update = self.lr * (target - prediction) ์์ธก์ด ์ ๋ต๋ณด๋ค ์์ผ๋ฉด โ update > 0: ๊ฐ์ค์น ์ฆ๊ฐ ์์ธก์ด ์ ๋ต๋ณด๋ค ํฌ๋ฉด โ update < 0: ๊ฐ์ค์น ๊ฐ์ ์์ธก์ด ์ ํํ๋ฉด โ update == 0: ๊ฐ์ค์น ๋ณํ ์์ self.weights += update * xi self.bias += update ๊ฐ ์ ๋ ฅ ๊ฐ์ ๋ฐ๋ผ ๊ฐ์ค์น ์กฐ์ ํญ์ ๋ฐ์ด์ด์ค๋ ๊ฐ์ด ์ ๋ฐ์ดํธ 2-6. ์๋ฌ ์นด์ดํธ total_error += int(update != 0.0) ์์ธก์ด ํ๋ ธ์ ๋๋ง ์๋ฌ๋ก ์ง๊ณ 2-7. ํ์ต ๊ฒฐ๊ณผ ์ถ๋ ฅ self.errors.append(total_error) print(f"Epoch {epoch+1}/{self.epochs}, Errors: {total_error}") ํ์ต์ด ์งํ๋ ์๋ก Errors๊ฐ ์ค์ด๋๋์ง ํ์ธ ๊ฐ๋ฅ ํ์ง๋ง XOR์ ์ค์ง ์์ โ ์ ํ ๋ถ๋ฆฌ ๋ถ๊ฐ๋ฅ ๋ฌธ์ 2-8. ์ต์ข ์์ธก ๊ฒฐ๊ณผ ํ์ธ ๊ฐ ๊ฒ์ดํธ์ ๋ํด ํ์ต์ด ๋๋๋ฉด ๋ค์์ ์ํ: for x in X_and: print(f"Input: {x}, Predicted Output: {ppn_and.predict(x)}") ํ์ต๋ ๊ฐ์ค์น๋ก ์๋ก์ด ์ ๋ ฅ์ ํ ์คํธํด๋ณด๋ ๊ณผ์ 2-9. ์์ฝ: ํผ์ ํธ๋ก ํ์ต ํ๋ฆ ์ ๋ ฅ X, ์ ๋ต y โ ๊ฐ์คํฉ ๊ณ์ฐ (wยทx + b) โ ๊ณ๋จ ํจ์๋ก ์์ธก โ ์ค์ฐจ ๊ณ์ฐ (target - predict) โ w, b ์ ๋ฐ์ดํธ โ ์๋ฌ ๊ธฐ๋ก โ epoch ๋ฐ๋ณต โ ํ์ต ์๋ฃ ํ ํ ์คํธ 3. XOR ๊ฒ์ดํธ๊ฐ ํผ์ ํธ๋ก ์ผ๋ก ์ ๋๋ ์ด์ ํผ์ ํธ๋ก ์ ์ง์ ํ๋๋ก ์ถ๋ ฅ์ ๋๋๋ ๋ชจ๋ธ XOR์ ์ด๋ค ์ง์ ์ผ๋ก๋ 0๊ณผ 1์ ๋๋ ์ ์์ ์ฆ, ์ ํ ๋ถ๋ฆฌ ๋ถ๊ฐ๋ฅ ๋ฌธ์ โ ํผ์ ํธ๋ก ํ๊ณ ํด๊ฒฐ์ฑ : ๋ค์ธต ํผ์ ํธ๋ก (MLP) ๋น์ ํ์ฑ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์๋์ธต + ๋น์ ํ ํ์ฑํ ํจ์ (์: sigmoid, ReLU)๋ฅผ ํ์ฉํ๊ณ , ์ค์ฐจ ์ญ์ ํ(Backpropagation)๋ก ํ์ตํจ
Study
ยท 2025-06-25
Day3 : Perceptron
๐ Perceptron๋? ํผ์ ํธ๋ก (Perceptron)์ ์๋ฌผํ์ ๋ด๋ฐ์ ์ํ์ ์ผ๋ก ๋ชจ๋ธ๋งํ ์ธ๊ณต ๋ด๋ฐ ๋ชจ๋ธ๋ก, ์ฌ๋ฌ ์ ๋ ฅ ์ ํธ๋ฅผ ๋ฐ์ ๊ฐ ์ ๋ ฅ์ ๋ํ ๊ฐ์ค์น(Weight)๋ฅผ ๊ณฑํ ํ, ์ด๋ค์ ๊ฐ์คํฉ(Weighted Sum)์ ๊ณ์ฐํ๊ณ , ํ์ฑํ ํจ์(Activation Function)๋ฅผ ํตํด ์ต์ข ์ถ๋ ฅ์ ๊ฒฐ์ ํ๋ ๊ตฌ์กฐ์ด๋ค. ๐ง ๊ตฌ์กฐ (Perceptron Structure) ์ ๋ ฅ(x) โ ๊ฐ์ค์น(w) โ ๊ฐ์คํฉ(โ) โ ํ์ฑํ ํจ์(f) โ ์ถ๋ ฅ(y) ์ ๋ ฅ (Input): AND, OR ๋ฑ ๋ ผ๋ฆฌ ์ฐ์ฐ์ ์ํ ์ ๋ ฅ ์ ํธ. ๊ฐ์ค์น (Weight): ์ ๋ ฅ ์ ํธ์ ์ค์๋๋ฅผ ๊ฒฐ์ ํ๋ฉฐ, ํ์ต์ ํตํด ์กฐ์ ๋จ. ๊ฐ์คํฉ (Weighted Sum): ๊ฐ ์ ๋ ฅ๊ณผ ๊ทธ์ ๋์ํ๋ ๊ฐ์ค์น์ ๊ณฑ์ ๋ชจ๋ ๋ํ ๊ฐ. ํ์ฑํ ํจ์ (Activation Function): ๊ฐ์คํฉ์ด ์๊ณ๊ฐ์ ๋์ผ๋ฉด 1, ๋์ง ๋ชปํ๋ฉด 0์ ์ถ๋ ฅํ๋ ํจ์. ๋ํ์ ์ผ๋ก ๋จ์ ๊ณ๋จ ํจ์ ์ฌ์ฉ. ์ถ๋ ฅ (Output): ์ต์ข ๊ฒฐ๊ณผ๊ฐ (๋ณดํต 0 ๋๋ 1์ ์ด์ง ์ถ๋ ฅ). ๐ฏ ์์ฝ ํผ์ ํธ๋ก ์ ์ด์ง ๋ถ๋ฅ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ์ ๊ฒฝ๋ง ๊ตฌ์กฐ์ด๋ค. ํ์ต์ ํตํด ์ ๋ ฅ ์ ํธ์ ์ค์๋๋ฅผ ๋ํ๋ด๋ ๊ฐ์ค์น๊ฐ ์กฐ์ ๋๋ค. ๋จ์ธต ํผ์ ํธ๋ก ์ ์ ํ ๋ถ๋ฆฌ ๊ฐ๋ฅํ ๋ฌธ์ ๋ง ํด๊ฒฐํ ์ ์๋ค. ๐จโ๐ป ์ค์ต ๐ก Code : AND & OR & NAND & XOR Gate Perceptron # AND & OR & NAND & XOR Gate Perceptron import numpy as np import matplotlib.pyplot as plt class Perceptron: def __init__(self, input_size, lr=0.1, epochs=10): self.weights = np.zeros(input_size) self.bias = 0 self.lr = lr self.epochs = epochs self.errors = [] def activation(self, x): return np.where(x > 0, 1, 0) def predict(self, x): linear_output = np.dot(x, self.weights) + self.bias return self.activation(linear_output) def train(self, X, y): for epoch in range(self.epochs): total_error = 0 for xi, target in zip(X, y): prediction = self.predict(xi) update = self.lr * (target - prediction) self.weights += update * xi self.bias += update total_error += int(update != 0.0) self.errors.append(total_error) print(f"Epoch {epoch+1}/{self.epochs}, Errors: {total_error}") # AND ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_and = np.array([[0,0],[0,1],[1,0],[1,1]]) y_and = np.array([0,0,0,1]) print(" AND Gate Training") ppn_and = Perceptron(input_size=2) ppn_and.train(X_and, y_and) print("\n AND Gate Test:") for x in X_and: print(f"Input: {x}, Predicted Output: {ppn_and.predict(x)}") # OR ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_or = np.array([[0,0],[0,1],[1,0],[1,1]]) y_or = np.array([0,1,1,1]) print("\n OR Gate Training") ppn_or = Perceptron(input_size=2) ppn_or.train(X_or, y_or) print("\n OR Gate Test:") for x in X_or: print(f"Input: {x}, Predicted Output: {ppn_or.predict(x)}") # NAND ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_nand = np.array([[0,0],[0,1],[1,0],[1,1]]) y_nand = np.array([1,1,1,0]) # AND์ ๋ฐ๋ print("\n NAND Gate Training") ppn_nand = Perceptron(input_size=2) ppn_nand.train(X_nand, y_nand) print("\n NAND Gate Test:") for x in X_nand: print(f"Input: {x}, Predicted Output: {ppn_nand.predict(x)}") # XOR ๊ฒ์ดํธ ๋ฐ์ดํฐ ๋ฐ ํ์ต X_xor = np.array([[0,0],[0,1],[1,0],[1,1]]) y_xor = np.array([0,1,1,0]) # ์ ํ ๋ถ๋ฆฌ ๋ถ๊ฐ๋ฅ print("\n XOR Gate Training") ppn_xor = Perceptron(input_size=2) ppn_xor.train(X_xor, y_xor) print("\n XOR Gate Test:") for x in X_xor: print(f"Input: {x}, Predicted Output: {ppn_xor.predict(x)}") โ Result : AND & OR & NAND & XOR Gate Perceptron AND Gate Training Epoch 1/10, Errors: 1 Epoch 2/10, Errors: 3 Epoch 3/10, Errors: 3 Epoch 4/10, Errors: 2 Epoch 5/10, Errors: 1 Epoch 6/10, Errors: 0 Epoch 7/10, Errors: 0 Epoch 8/10, Errors: 0 Epoch 9/10, Errors: 0 Epoch 10/10, Errors: 0 AND Gate Test: Input: [0 0], Predicted Output: 0 Input: [0 1], Predicted Output: 0 Input: [1 0], Predicted Output: 0 Input: [1 1], Predicted Output: 1 OR Gate Training Epoch 1/10, Errors: 1 Epoch 2/10, Errors: 2 Epoch 3/10, Errors: 1 Epoch 4/10, Errors: 0 Epoch 5/10, Errors: 0 Epoch 6/10, Errors: 0 Epoch 7/10, Errors: 0 Epoch 8/10, Errors: 0 Epoch 9/10, Errors: 0 Epoch 10/10, Errors: 0 OR Gate Test: Input: [0 0], Predicted Output: 0 Input: [0 1], Predicted Output: 1 Input: [1 0], Predicted Output: 1 Input: [1 1], Predicted Output: 1 NAND Gate Training Epoch 1/10, Errors: 2 Epoch 2/10, Errors: 3 Epoch 3/10, Errors: 3 Epoch 4/10, Errors: 0 Epoch 5/10, Errors: 0 Epoch 6/10, Errors: 0 Epoch 7/10, Errors: 0 Epoch 8/10, Errors: 0 Epoch 9/10, Errors: 0 Epoch 10/10, Errors: 0 NAND Gate Test: Input: [0 0], Predicted Output: 1 Input: [0 1], Predicted Output: 1 Input: [1 0], Predicted Output: 1 Input: [1 1], Predicted Output: 0 XOR Gate Training Epoch 1/10, Errors: 2 Epoch 2/10, Errors: 3 Epoch 3/10, Errors: 4 Epoch 4/10, Errors: 4 Epoch 5/10, Errors: 4 Epoch 6/10, Errors: 4 Epoch 7/10, Errors: 4 Epoch 8/10, Errors: 4 Epoch 9/10, Errors: 4 Epoch 10/10, Errors: 4 XOR Gate Test: Input: [0 0], Predicted Output: 1 Input: [0 1], Predicted Output: 1 Input: [1 0], Predicted Output: 0 Input: [1 1], Predicted Output: 0 ๐ก Code : ๊ฒฝ๊ณ ๊ฒฐ์ ์๊ฐํ ํจ์ (AND, OR, NAND, XOR) # ๊ฒฝ๊ณ ๊ฒฐ์ ์๊ฐํ ํจ์ (AND, OR, NAND, XOR) from matplotlib.colors import ListedColormap import matplotlib.pyplot as plt import numpy as np def plot_decision_boundary(X, y, model, title='Perceptron Decision Boundary'): cmap_light = ListedColormap(['#FFDDDD', '#DDDDFF']) # ๋ฐฐ๊ฒฝ ์์ cmap_bold = ListedColormap(['#FF0000', '#0000FF']) # ์ ์์ h = .02 # mesh grid ๊ฐ๊ฒฉ x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Z = model.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.figure(figsize=(6, 5)) plt.contourf(xx, yy, Z, cmap=cmap_light) plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor='k', s=100, marker='o') plt.xlabel('Input 1') plt.ylabel('Input 2') plt.title(title) plt.grid(True) plt.show() # AND ๊ฒ์ดํธ ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ plot_decision_boundary(X_and, y_and, ppn_and, title='AND Gate Decision Boundary') # OR ๊ฒ์ดํธ ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ plot_decision_boundary(X_or, y_or, ppn_or, title='OR Gate Decision Boundary') # NAND ๊ฒ์ดํธ ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ plot_decision_boundary(X_nand, y_nand, ppn_nand, title='NAND Gate Decision Boundary') # XOR ๊ฒ์ดํธ ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ plot_decision_boundary(X_xor, y_xor, ppn_xor, title='XOR Gate Decision Boundary') โ Result : ๊ฒฝ๊ณ ๊ฒฐ์ ์๊ฐํ ํจ์ (AND, OR, NAND, XOR) ๐ก Code : # ์ค๋ฅ ์๊ฐํ (AND, OR, NAND, XOR) # ์ค๋ฅ ์๊ฐํ (AND, OR, NAND, XOR) plt.figure(figsize=(8, 5)) plt.plot(range(1, len(ppn_and.errors) + 1), ppn_and.errors, marker='o', label='AND Gate') plt.plot(range(1, len(ppn_or.errors) + 1), ppn_or.errors, marker='s', label='OR Gate') plt.plot(range(1, len(ppn_nand.errors) + 1), ppn_nand.errors, marker='^', label='NAND Gate') plt.plot(range(1, len(ppn_xor.errors) + 1), ppn_xor.errors, marker='x', label='XOR Gate') plt.xlabel('Epochs') plt.ylabel('Number of Errors') plt.title('Perceptron Learning Error Over Epochs') plt.legend() plt.grid(True) plt.show() โ Result : ์ค๋ฅ ์๊ฐํ (AND, OR, NAND, XOR) ๐ฌ Comment ํผ์ ํธ๋ก : ์ ๋ ฅ ๋ฒกํฐ์ ๊ฐ์ค์น๋ฅผ ๊ณฑํ ํฉ์ด ๊ธฐ์ค(0)์ ๋๋์ง ํ๋จํ๊ณ , ํ์ต ๊ณผ์ ์์๋ ํ๋ฆฐ ๋งํผ๋ง ์กฐ์ ํ๋ฉฐ ์ ํ ๋ถ๋ฆฌ๋ฅผ ๋ฐฐ์ฐ๋ ๊ตฌ์กฐ XOR์ ์ ํ ๋ถ๋ฆฌ ๋ถ๊ฐ๋ฅํ ๋ฌธ์ ์ด๊ธฐ ๋๋ฌธ์ ๋จ์ธต ํผ์ ํธ๋ก ์ผ๋ก๋ ํด๊ฒฐํ ์ ์๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๋ค์ธต ํผ์ ํธ๋ก (MLP)์ด๋ ๋น์ ํ ๋ณํ์ด ํ์ํ๋ค. ๐ก Code : MLP๋ก XOR ๋ฌธ์ ํด๊ฒฐ import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap class MultiLayerPerceptron: def __init__(self, input_size=2, hidden_size=4, output_size=1, lr=0.5, epochs=1000): self.W1 = np.random.uniform(-1, 1, (input_size, hidden_size)) self.b1 = np.zeros((1, hidden_size)) self.W2 = np.random.uniform(-1, 1, (hidden_size, output_size)) self.b2 = np.zeros((1, output_size)) self.lr = lr self.epochs = epochs self.losses = [] def sigmoid(self, x): return 1 / (1 + np.exp(-np.clip(x, -250, 250))) def sigmoid_derivative(self, x): return x * (1 - x) def forward(self, X): self.z1 = np.dot(X, self.W1) + self.b1 self.a1 = self.sigmoid(self.z1) self.z2 = np.dot(self.a1, self.W2) + self.b2 self.a2 = self.sigmoid(self.z2) return self.a2 def backward(self, X, y, output): m = X.shape[0] dZ2 = output - y dW2 = (1 / m) * np.dot(self.a1.T, dZ2) db2 = (1 / m) * np.sum(dZ2, axis=0, keepdims=True) dZ1 = np.dot(dZ2, self.W2.T) * self.sigmoid_derivative(self.a1) dW1 = (1 / m) * np.dot(X.T, dZ1) db1 = (1 / m) * np.sum(dZ1, axis=0, keepdims=True) self.W2 -= self.lr * dW2 self.b2 -= self.lr * db2 self.W1 -= self.lr * dW1 self.b1 -= self.lr * db1 def train(self, X, y): for epoch in range(self.epochs): output = self.forward(X) loss = np.mean((output - y) ** 2) self.losses.append(loss) self.backward(X, y, output) #if epoch % 200 == 0: # print(f"Epoch {epoch}/{self.epochs}, Loss: {loss:.6f}") def predict(self, X): output = self.forward(X) return (output > 0.5).astype(int) def predict_prob(self, X): return self.forward(X).ravel() # ๊ฒฐ์ ๊ฒฝ๊ณ์ฉ # === XOR ๋ฐ์ดํฐ === X_xor = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y_xor = np.array([[0], [1], [1], [0]]) # === ํ์ต === print("\n=== XOR Gate Multi-Layer Perceptron Training ===") mlp = MultiLayerPerceptron(input_size=2, hidden_size=2, lr=0.5, epochs=10000) mlp.train(X_xor, y_xor) # === ์์ธก ๊ฒฐ๊ณผ ์ถ๋ ฅ === print("\nXOR GATE Test (Multi-Layer Perceptron):") xor_predictions = mlp.predict(X_xor) for i, x in enumerate(X_xor): predicted = xor_predictions[i][0] actual = y_xor[i][0] result = "โ" if predicted == actual else "โ" print(f"Input: {x}, Predicted: {predicted}, Actual: {actual}, {result}") # === ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ ํจ์ === def plot_decision_boundary(X, y, model, title="Decision Boundary"): cmap_light = ListedColormap(['#FFDDDD', '#DDDDFF']) cmap_bold = ListedColormap(['#FF0000', '#0000FF']) h = .01 x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5 y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) grid = np.c_[xx.ravel(), yy.ravel()] Z = model.predict_prob(grid) Z = Z.reshape(xx.shape) plt.figure(figsize=(6, 5)) plt.contourf(xx, yy, Z > 0.5, cmap=cmap_light) plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), cmap=cmap_bold, edgecolor='k', s=120) plt.title(title) plt.xlabel("Input 1") plt.ylabel("Input 2") plt.grid(True) plt.show() # === ๊ฒฐ์ ๊ฒฝ๊ณ ์๊ฐํ === plot_decision_boundary(X_xor, y_xor, mlp, title="XOR MLP Decision Boundary") # === ์์ค ๊ณก์ ์๊ฐํ === plt.figure(figsize=(8, 5)) plt.plot(range(mlp.epochs), mlp.losses, color='purple') plt.title("MLP Training Loss on XOR Problem") plt.xlabel("Epochs") plt.ylabel("Mean Squared Error") plt.grid(True) plt.show() โ Result : MLP๋ก XOR ๋ฌธ์ ํด๊ฒฐ === XOR Gate Multi-Layer Perceptron Training === XOR GATE Test (Multi-Layer Perceptron): Input: [0 0], Predicted: 0, Actual: 0, โ Input: [0 1], Predicted: 1, Actual: 1, โ Input: [1 0], Predicted: 1, Actual: 1, โ Input: [1 1], Predicted: 0, Actual: 0, โ
Study
ยท 2025-06-25
Day2 : OpenCV
๐ OpenCV๋? OpenCV(Open Source Computer Vision Library)๋ ์ค์๊ฐ ์ปดํจํฐ ๋น์ ๋ฐ ๋จธ์ ๋ฌ๋์ ์ํ ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๋ค์ํ ์ด๋ฏธ์ง/๋น๋์ค ์ฒ๋ฆฌ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ฉฐ, Python, C++, Java ๋ฑ ๋ค์ํ ์ธ์ด์์ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค. ๐ CUDA ๋ชจ๋์ ์ญํ GPU ๊ฐ์์ ํ์ฉํ ๊ณ ์ ์ด๋ฏธ์ง ์ฒ๋ฆฌ ์ํ OpenCV์ ์ผ๋ถ ํจ์๋ค์ CUDA๋ฅผ ํตํด ๋ณ๋ ฌ ์ฒ๋ฆฌ๋์ด ์ฑ๋ฅ์ ํฅ์์ํด ์ฌ์ฉ ์: cv2.cuda.GpuMat, cv2.cuda.filter2D(), cv2.cuda.resize() ๋ฑ ๐ ๏ธ ์์ ํ ๋๋ ํ ๋ฆฌ ์์ฑ ๋ฐ ํ๊ฒฝ ์ค์ # 1. ์์ ๋๋ ํ ๋ฆฌ ์์ฑ mkdir opencv # ๋๋ ํ ๋ฆฌ ์ด๋ฆ: opencv cd opencv # ํด๋น ๋๋ ํ ๋ฆฌ๋ก ์ด๋ # 2. ๊ฐ์ ํ๊ฒฝ ์์ฑ ๋ฐ ํ์ฑํ python3 -m venv .env # ๊ฐ์ ํ๊ฒฝ ์์ฑ (ํด๋ ์ด๋ฆ: .env) source .env/bin/activate # ๊ฐ์ ํ๊ฒฝ ํ์ฑํ # 3. ํจํค์ง ์ค์น pip install opencv-python # OpenCV ๊ธฐ๋ณธ ๊ธฐ๋ฅ(core, imgproc ๋ฑ) pip install opencv-contrib-python # ์ถ๊ฐ ๋ชจ๋(contrib ํฌํจ) pip install -U pip # pip ์ต์ ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋ โ ์ค์น ํ์ธ (Python ์ธํฐํ๋ฆฌํฐ ์คํ) >>> import numpy as np >>> import cv2 >>> np.__version__ '2.2.6' # ์ค์น๋ NumPy ๋ฒ์ ์ถ๋ ฅ >>> cv2.__version__ '4.11.0' # ์ค์น๋ OpenCV ๋ฒ์ ์ถ๋ ฅ >>> exit() # Python ์ธํฐํ๋ฆฌํฐ ์ข ๋ฃ ๐จ ์์ ์ ๋ณด ๐ ์ฐธ๊ณ ์ฌ์ดํธ W3Schools - RGB Colors ๐ RGB (Red, Green, Blue) ๊ฐ ์์ ์ฑ๋: 0~255 (8bit) R (Red): 8bit G (Green): 8bit B (Blue): 8bit ํฝ์ 1๊ฐ = 24bit (8bit ร 3) ๐จ HSL (Hue, Saturation, Lightness) H: ์์ (Hue) โ 0 ~ 360ยฐ S: ์ฑ๋ (Saturation) โ 0 ~ 100% L: ๋ฐ๊ธฐ (Lightness) โ 0 ~ 100% ๐ RGB vs HSL ์ฐจ์ด์ ํญ๋ชฉ RGB HSL ๊ตฌ์ฑ Red, Green, Blue (๊ฐ 0~255) Hue (0~360), Saturation & Lightness (0~100%) ์ง๊ด์ฑ ์ปดํจํฐ์์ ์ฌ์ฉํ๊ธฐ ์ ํฉ ์ฌ๋์ด ์์ ์ดํดํ๊ธฐ ์ฌ์ ์ ์กฐ์ ์์ ์กฐ์ ์ด ๋ณต์กํจ ์ฑ๋/๋ฐ๊ธฐ ์กฐ์ ์ด ์ฉ์ดํจ ์ฉ๋ ๋์คํ๋ ์ด, ์ด๋ฏธ์ง ์ฒ๋ฆฌ ๋ฑ ๋์์ธ, ์์ ์ ํ ๋๊ตฌ ๋ฑ์ ์ ์ฉ โ ์์ฝ: RGB๋ ํ๋ฉด ์ถ๋ ฅ/์ฒ๋ฆฌ์ ์ ํฉํ ๋์งํธ ์ ํํ ๋ฐฉ์ HSL์ ์์ ๊ตฌ์ฑ์์๋ฅผ ๋ถ๋ฆฌํด ์ฌ๋์ด ์ดํดํ๊ฑฐ๋ ์กฐ์ ํ๊ธฐ ์ฌ์ด ๋ฐฉ์ ๐ ๋ฉ๋ชจ vi ex1.py : python ์คํฌ๋ฆฝํธ ์์ฑ python ex1.py : ์์ฑ๋ ์คํฌ๋ฆฝํธ ์คํ jpg : ํ์ผ์ด ์๊ณ ์๋๊ฐ ๋น ๋ฅด๋ฉฐ, ์ฃผ๋ก ์ฌ์ง์ด๋ ์น ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง์ ์ฌ์ฉ png : ํ์ง ๋ณด์กด, ํฌ๋ช ๋ฐฐ๊ฒฝ์ด ํ์ํ ๊ฒฝ์ฐ ์ฌ์ฉ ๐จโ๐ป ์ค์ต ๐ก Code : ์ด๋ฏธ์ง Read / Write / Display # ex1.py import numpy as np import cv2 # ์ด๋ฏธ์ง ํ์ผ์ Read img = cv2.imread("Rengoku.jpg") # Image ๋ ์ด๋ฆ์ Display ์ฐฝ ์์ฑ cv2.namedWindow("image", cv2.WINDOW_NORMAL) # Numpy ndarray H/W/C order print(img.shape) # Read ํ ์ด๋ฏธ์ง ํ์ผ์ Display cv2.imshow("image", img) # ๋ณ๋ ํค ์ ๋ ฅ์ด ์์๋ ๊น์ง ๋๊ธฐ cv2.waitKey(0) # ex1_output.jpg ๋ก ์ฝ์ ์ด๋ฏธ์ง ํ์ผ์ ์ ์ฅ cv2.imwrite("ex1_output.jpg", img) # Destory all windows cv2.destroyAllWindows() โ Quiz: ์ด๋ฏธ์ง Read / Write / Display 1. print(img.shape)์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ๋ฌด์จ ์๋ฏธ์ผ๊น? 2. ๋ณธ์ธ์ด ์ข์ํ๋ ์ฌ์ง์ web ์์ ๋ค์ด๋ฐ์์ OpenCV API๋ฅผ ์ฌ์ฉํด์ Display ๋ฐ ํ์ผ๋ก ์ ์ฅํด๋ณด์. 3. ํ์ฌ๋ ๋ณ๋์ ํค ์ ๋ ฅ์ด ์์ ๋๊น์ง cv2.waitKey(0) ํจ์์์ ๋๊ธฐํ๊ฒ ๋๋ค. ์ฝ๋๋ฅผ ์ถ๊ฐํด์ ์๋ฌธ์ โsโ ํค๋ฅผ ์ ๋ ฅ๋ฐ์ ๋๋ง ์ด๋ฏธ์ง ํ์ผ์ ์ ์ฅํ๊ณ ๋ค๋ฅธ ํค๊ฐ ์ ๋ ฅ๋๋ฉด ์ด๋ฏธ์ง ํ์ผ์ ์ ์ฅํ์ง ์๊ฒ ์์ ํด๋ณด์. ๐ก Code : RGB/HSV Color Space (์ ๊ณต๊ฐ) # ex2.py import numpy as np import cv2 # ์ด๋ฏธ์ง ํ์ผ์ Read ํ๊ณ Color space ์ ๋ณด ์ถ๋ ฅ color = cv2.imread("Rengoku.jpg", cv2.IMREAD_COLOR) print(color.shape) height,width,channels = color.shape cv2.imshow("Original Image", color) # Color channel ์ B,G,R ๋ก ๋ถํ ํ์ฌ ์ถ๋ ฅ b,g,r = cv2.split(color) rgb_split = np.concatenate((b,g,r),axis=1) cv2.imshow("BGR Channels",rgb_split) # ์๊ณต๊ฐ์ BGR ์์ HSV ๋ก ๋ณํ hsv = cv2.cvtColor(color, cv2.COLOR_BGR2HSV) # Channel ์ H,S,V ๋ก ๋ถํ ํ์ฌ ์ถ๋ ฅ h,s,v = cv2.split(hsv) hsv_split = np.concatenate((h,s,v),axis=1) cv2.imshow("Split HSV", hsv_split) โ Quiz : RGB/HSV Color Space (์ ๊ณต๊ฐ) 1. ์ ์๊ณต๊ฐ ์ด๋ฏธ์ง์ ๋งํฌ๋ก ์ด๋ํด์ ๊ฐ ์ ๊ณต๊ฐ์ ํํ ๋ฐฉ๋ฒ์ ์ดํดํด ๋ณด์. 2. HSV color space๊ฐ ์ด๋ค ๊ฒฝ์ฐ์ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉ๋ ๊น? 3. HSV๋ก ๋ณํ๋ ์ด๋ฏธ์ง๋ฅผ BGR์ด ์๋ RGB๋ก ๋ค์ ๋ณํํด์ ์ถ๋ ฅํด ๋ณด์. 4. COLOR_RGB2GRAY๋ฅผ ์ฌ์ฉํด์ ํ๋ฐฑ์ผ๋ก ๋ณํํด ์ถ๋ ฅํด ๋ณด์. ๐ก Code : Crop / Resize (์๋ฅด๊ธฐ / ํฌ๊ธฐ ์กฐ์ ) # ex3.py import numpy as np import cv2 # ์ด๋ฏธ์ง ํ์ผ์ Read img = cv2.imread("Rengoku.jpg") # Crop 300x400 from original image from (100, 50)=(x, y) # ์ธ๋ก(y): 100:500 โ 500 - 100 = 400ํฝ์ # ๊ฐ๋ก(x): 500:1200 โ 1200 - 500 = 700ํฝ์ cropped = img[100:500, 500:1200] # Resize cropped image from 300x400 to 400x200 resized = cv2.resize(cropped, (800,200)) # Display all cv2.imshow("Original", img) cv2.imshow("Cropped image", cropped) cv2.imshow("Resized image", resized) cv2.imwrite("ex3_cropped.jpg", cropped) cv2.imwrite("ex3_resized.jpg", resized) cv2.waitKey(0) cv2.destroyAllWindows() โ Quiz : Crop / Resize (์๋ฅด๊ธฐ / ํฌ๊ธฐ ์กฐ์ ) 1. Input image ๋ฅผ ๋ณธ์ธ์ด ์ข์ํ๋ ์ธ๋ฌผ ์ฌ์ง์ผ๋ก ๋ณ๊ฒฝํด์ ์ ์ฉํ์. ๊ทธ๋ฆฌ๊ณ ๋ณธ์ธ์ด ์ฌ์ฉํ input image ์ size ๋ฅผ ํ์ธํด ๋ณด์. 2. ๋ณธ์ธ์ด ์ฌ์ฉํ ์ด๋ฏธ์ง์ ์ผ๊ตด ์์ญ๋ง crop ํด์ display ํด ๋ณด์. 3. ์๋ณธ ์ด๋ฏธ์ง์ ์ ํํ 1.5๋ฐฐ๋งํผ ์ด๋ฏธ์ง๋ฅผ ํ๋ํด์ ํ์ผ๋ก ์ ์ฅํด ๋ณด์. 4. openCV ์ rotate API ๋ฅผ ์ฌ์ฉํด์ ์ฐ์ธก์ผ๋ก 90๋๋งํผ ํ์ ๋ ์ด๋ฏธ์ง๋ฅผ ์ถ๋ ฅํด ๋ณด์. ๐ก Code : ์ญ์ (Reverse Image) # ex4.py import numpy as np import cv2 src = cv2.imread("Rengoku.jpg", cv2.IMREAD_COLOR) dst = cv2.bitwise_not(src) cv2.imshow("src", src) cv2.imshow("dst", dst) cv2.imwrite("ex4_reverse.jpg", dst) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ์ญ์ (Reverse Image) 1. AND, OR, XOR ์ฐ์ฐ์ ๋ํด์ ํ์ธํด ๋ณด์. ๐ก Code : ์ด์งํ (Binary) # ex5.py import numpy as np import cv2 src = cv2.imread("Rengoku.jpg", cv2.IMREAD_COLOR) gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) ret, dst = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY) cv2.imshow("dst", dst) cv2.imwrite("ex5_binary.jpg", dst) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ์ด์งํ (Binary) 1. ์๊ณ๊ฐ์ ๋ณํ์์ผ ๋ณด์. ๐ก Code : ํ๋ฆผํจ๊ณผ (Blur) # ex6.py import numpy as np import cv2 src = cv2.imread("Rengoku.jpg", cv2.IMREAD_COLOR) dst = cv2.blur(src, (9, 9), anchor=(-1,- 1), borderType=cv2.BORDER_DEFAULT) cv2.imshow("dst", dst) cv2.imwrite("ex6_blur.jpg", dst) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ํ๋ฆผํจ๊ณผ (Blur) 1. Kernel Size๋ฅผ ๋ณ๊ฒฝํ์ฌ ๋ณด์. 2. borderType์ ๋ณ๊ฒฝํ์ฌ ๋ณด์.(cv2.BORDER_REFLECT) ๐ก Code : ๊ฐ์ฅ์๋ฆฌ ๊ฒ์ถ (Edge) # ex7.py import numpy as np import cv2 src = cv2.imread("Rengoku.jpg", cv2.IMREAD_COLOR) gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY) sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, 3) cv2.imshow("sobel", sobel) cv2.imwrite("ex7_edge.jpg", sobel) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ๊ฐ์ฅ์๋ฆฌ ๊ฒ์ถ (Edge) 1. Laplacian ๋ณํ์ ์ ์ฉํด ๋ณด์. 2. Canny Edge Detection์ ์ ์ฉํด ๋ณด์. ๐ก Code : ๋ฐฐ์ด ๋ณํฉ (add Weighted) # ex8.py import numpy as np import cv2 src = cv2.imread("RGB.png", cv2.IMREAD_COLOR) hsv = cv2.cvtColor(src, cv2.COLOR_BGR2HSV) # 1. Red ๋ง์คํฌ ์์ฑ lower_red = cv2.inRange(hsv, (0, 100, 100), (5, 255, 255)) upper_red = cv2.inRange(hsv, (170, 100, 100), (180, 255, 255)) mask_red = cv2.addWeighted(lower_red, 1.0, upper_red, 1.0, 0.0) # 2. Green ๋ง์คํฌ ์์ฑ mask_green = cv2.inRange(hsv, (40, 100, 100), (85, 255, 255)) # 3. Blue ๋ง์คํฌ ์์ฑ mask_blue = cv2.inRange(hsv, (100, 100, 100), (130, 255, 255)) # 4. ๊ฐ ์์ ์ถ์ถ (HSV โ BGR ๋ณํ ํฌํจ) red = cv2.bitwise_and(hsv, hsv, mask=mask_red) green = cv2.bitwise_and(hsv, hsv, mask=mask_green) blue = cv2.bitwise_and(hsv, hsv, mask=mask_blue) red = cv2.cvtColor(red, cv2.COLOR_HSV2BGR) green = cv2.cvtColor(green, cv2.COLOR_HSV2BGR) blue = cv2.cvtColor(blue, cv2.COLOR_HSV2BGR) # 5. ํ๋ฉด ์ถ๋ ฅ cv2.imshow("Original", src) cv2.imshow("Red", red) cv2.imshow("Green", green) cv2.imshow("Blue", blue) cv2.imwrite("ex8_original.png", src) cv2.imwrite("ex8_red.png", red) cv2.imwrite("ex8_green.png", green) cv2.imwrite("ex8_blue.png", blue) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ๋ฐฐ์ด ๋ณํฉ (add Weighted) 1. lower_red ๊ฐ์ ๋ฒ์๋ฅผ ๋ณ๊ฒฝํด ๋ณด์. 2. upper_red ๊ฐ์ ๋ฒ์๋ฅผ ๋ณ๊ฒฝํด ๋ณด์. 3. addWeighted์ gamma ๊ฐ์ ๋ณ๊ฒฝํด ๋ณด์. ๐ก Code : ์ฑ๋ ๋ถ๋ฆฌ ๋ฐ ๋ณํฉ # ex9.py import numpy as np import cv2 # ์ด๋ฏธ์ง ์ฝ๊ธฐ src = cv2.imread("RGB.png", cv2.IMREAD_COLOR) # ์ฑ๋ ๋ถ๋ฆฌ b, g, r = cv2.split(src) # ์ฑ๋ ์์ ๋ณ๊ฒฝ (RGB์ฒ๋ผ ๋ณด์ด๊ฒ) inverse = cv2.merge((r, g, b)) # ํ๋ฉด ์ถ๋ ฅ cv2.imshow("b", b) cv2.imshow("g", g) cv2.imshow("r", r) cv2.imshow("inverse", inverse) # ์ด๋ฏธ์ง ์ ์ฅ cv2.imwrite("ex9_blue_gray.png", b) cv2.imwrite("ex9_green_gray.png", g) cv2.imwrite("ex9_red_gray.png", r) cv2.imwrite("ex9_inverse.png", inverse) cv2.waitKey() cv2.destroyAllWindows() โ Quiz : ์ฑ๋ ๋ถ๋ฆฌ ๋ฐ ๋ณํฉ 1. Numpy ํํ์ ์ฑ๋ ๋ถ๋ฆฌ๋ฅผ ์ ์ฉํด ๋ณด์. b = src[:, :, 0] g = src[:, :, 1] r = src[:, :, 2] 2. ๋น ์ด๋ฏธ์ง๋ฅผ ์ ์ฉํด ๋ณด์. height, width, channel = src.shape zero = np.zeros((height, width, 1), dtype=np.uint8) bgz = cv2.merge((b, g, zero)) ๐ก Code : ๋์์ ํ์ผ์ ์ฝ๊ณ ๋ณด์ฌ์ฃผ๊ธฐ # ex10.py import numpy as np import cv2 cap = cv2.VideoCapture("son.mp4") save_count = 1 # ์ ์ฅํ ์ด๋ฏธ์ง ๋ฒํธ ์ด๊ธฐํ while cap.isOpened(): ret, frame = cap.read() # (2) ํ๋ ์ ์ฝ๊ธฐ ์คํจ โ ์์ ๋ โ ์ฒ์๋ถํฐ ๋ค์ if not ret: print("Restarting video...") cap.set(cv2.CAP_PROP_POS_FRAMES, 0) continue # (3) ํ๋ ์ ํฌ๊ธฐ 50% ์ถ์ resized = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5) # ์ถ๋ ฅ cv2.imshow("Resized Frame", resized) # (1) ๊ณ ์ ๋ ์๋๋ก ์ฌ์ (์ฝ 30fps) key = cv2.waitKey(90) # (4) 'c' ํค ์ ๋ ฅ ์ ์ด๋ฏธ์ง ์ ์ฅ if key & 0xFF == ord('c'): filename = f"{save_count:03}.jpg" cv2.imwrite(filename, resized) print(f"Saved {filename}") save_count += 1 # 'q' ํค ์ ๋ ฅ ์ ์ข ๋ฃ if key & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() โ Quiz : ๋์์ ํ์ผ์ ์ฝ๊ณ ๋ณด์ฌ์ฃผ๊ธฐ 1. ๋์์์ด ๋๋ฌด ๋น ๋ฅด๊ฒ ์ฌ์๋๋ค. ์ด์ ๋ฅผ ์ฐพ์๋ณด๊ณ ์ ์์ ์ธ ์๋๋ก ์ฌ์๋ ์ ์๋๋ก ์์ ํด ๋ณด์. 2. ๋์์์ด ๋๊น์ง ์ฌ์๋๋ฉด ๋ ์ด์ frame์ ์ฝ์ง ๋ชปํด ์ข ๋ฃ๋๋ค. ๋์์์ด ๋๊น์ง ์ฌ์๋๋ฉด ๋ค์ ์ฒ์๋ถํฐ ๋ฐ๋ณต๋ ์ ์๋๋ก ์์ ํด ๋ณด์. 3. ๋์์ ํฌ๊ธฐ๋ฅผ ๋ฐ์ผ๋ก resizeํด์ ์ถ๋ ฅํด ๋ณด์. 4. ๋์์ ์ฌ์ ์ค 'c' ํค ์ ๋ ฅ์ ๋ฐ์ผ๋ฉด ํด๋น ํ๋ ์์ ์ด๋ฏธ์ง ํ์ผ๋ก ์ ์ฅํ๋ ์ฝ๋๋ฅผ ์์ฑํด ๋ณด์. ํ์ผ ์ด๋ฆ์ 001.jpg, 002.jpg ๋ฑ์ผ๋ก overwrite ๋์ง ์๊ฒ ํ์. ๐ก Code : ์นด๋ฉ๋ผ๋ก๋ถํฐ input ์ ๋ฐ์ ๋ณด์ฌ์ฃผ๊ณ ๋์์ ํ์ผ๋ก ์ ์ฅํ๊ธฐ # ex11.py import numpy as np import cv2 # Read from the first camera device cap = cv2.VideoCapture(0) w = 640 #1280#1920 h = 480 #720#1080 cap.set(cv2.CAP_PROP_FRAME_WIDTH, w) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h) # ์ฑ๊ณต์ ์ผ๋ก video device ๊ฐ ์ด๋ ธ์ผ๋ฉด while ๋ฌธ ๋ฐ๋ณต while(cap.isOpened()): # ํ ํ๋ ์์ ์ฝ์ด์ด ret, frame = cap.read() if ret is False: print("Can't receive frame (stream end?). Exiting ...") break # Display cv2.imshow("Camera", frame) # 1 ms ๋์ ๋๊ธฐํ๋ฉฐ ํค ์ ๋ ฅ์ ๋ฐ๊ณ 'q' ์ ๋ ฅ ์ ์ข ๋ฃ key = cv2.waitKey(1) if key & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() โ Quiz : ์นด๋ฉ๋ผ๋ก๋ถํฐ input ์ ๋ฐ์ ๋ณด์ฌ์ฃผ๊ณ ๋์์ ํ์ผ๋ก ์ ์ฅํ๊ธฐ 1. ๊ฐ์ง๊ณ ์๋ ์นด๋ฉ๋ผ์ ์ง์ ๊ฐ๋ฅํ ํด์๋๋ฅผ ํ์ธ ํ ์นด๋ฉ๋ผ ํด์๋๋ฅผ ๋ณ๊ฒฝํด ๋ณด์. 2. ์นด๋ฉ๋ผ Input์ "output.mp4" ๋์์ ํ์ผ๋ก ์ ์ฅํ๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด ๋ณด์. ๐ ๋ฉ๋ชจ sudo apt install v4l-utils : ์นด๋ฉ๋ผ ์ง์ ํด์๋ ํ์ธ์ฉ ๋๊ตฌ ์ค์น v4l2-ctl -d /dev/video0 โlist-formats-ext : ํด๋น ์นด๋ฉ๋ผ์ ํด์๋ ๋ฐ ํฌ๋งท ๋ชฉ๋ก ์ถ๋ ฅ ๐ก Code : Text / Line / Ractangle # ex12.py import numpy as np import cv2 cap = cv2.VideoCapture(0) # ๋๊ทธ๋ผ๋ฏธ๋ฅผ ๊ทธ๋ฆด ์ขํ๋ฅผ ์ ์ฅํ ๋ฆฌ์คํธ circle_centers = [] def draw_circle(event, x, y, flags, param): if event == cv2.EVENT_LBUTTONDOWN: # ๋ง์ฐ์ค ์ผ์ชฝ ๋ฒํผ ํด๋ฆญ ์ ์ขํ ์ ์ฅ circle_centers.append((x, y)) cv2.namedWindow("Camera") cv2.setMouseCallback("Camera", draw_circle) topLeft = (50+100, 50) bottomRight = (300+100, 300) while cap.isOpened(): ret, frame = cap.read() if not ret: break # Line cv2.line(frame, (topLeft[0] + 80, topLeft[1]), (bottomRight[0] + 80, bottomRight[1]), (0, 255, 0), 3) # Rectangle cv2.rectangle(frame, [pt+80 for pt in topLeft], [pt+50 for pt in bottomRight], (255, 0, 255), 3) # Text font = cv2.FONT_ITALIC cv2.putText(frame, 'hhhong', [pt-180 for pt in bottomRight], font, 2, (0, 255, 255), 5) # ์ ์ฅ๋ ์ขํ์ ๋๊ทธ๋ผ๋ฏธ ๊ทธ๋ฆฌ๊ธฐ for center in circle_centers: cv2.circle(frame, center, 30, (255, 255, 0), 3) # ๋ฐ์ง๋ฆ 30, ๋๊ป 3, ์์ (BGR) cv2.imshow("Camera", frame) key = cv2.waitKey(1) if key & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows() โ Quiz : Text / Line / Ractangle 1. Text ๋ฌธ๊ตฌ / Font / ์์ / ํฌ๊ธฐ / ๊ตต๊ธฐ / ์ถ๋ ฅ์์น ๋ฑ ๋ชจ๋ ๊ฐ์ ๋ณ๊ฒฝํด ๋ณด์. 2. ๋๊ทธ๋ผ๋ฏธ๋ฅผ ๊ทธ๋ฆฌ๋ ํจ์๋ฅผ ์ฐพ์์ ์ ์ฉํด ๋ณด์. 3. ๋ง์ฐ์ค ์ผ์ชฝ ๋ฒํผ์ click ํ๋ฉด ํด๋น ์์น์ ๋๊ทธ๋ผ๋ฏธ๊ฐ ๊ทธ๋ ค์ง๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํด ๋ณด์. (Reference : cv2.EVENT_LBUTTONDOWN) ๐ก Code : Trackbar # ex13.py import cv2 topLeft = (50, 50) bold = 0 r, g, b = 255, 255, 0 # ์ด๊ธฐ ํ ์คํธ ์์: ๋ ธ๋์ (BGR = (0, 255, 255)) # bold ํธ๋๋ฐ ์ฝ๋ฐฑ def on_bold_trackbar(value): global bold bold = value global r r = value def on_g_trackbar(value): global g g = value def on_b_trackbar(value): global b b = value # ์นด๋ฉ๋ผ ์ฐ๊ฒฐ cap = cv2.VideoCapture(0) # ์๋์ฐ ๋ฐ ํธ๋๋ฐ ์์ฑ cv2.namedWindow("Camera") cv2.createTrackbar("bold", "Camera", bold, 30, on_bold_trackbar) cv2.createTrackbar("R", "Camera", r, 255, on_r_trackbar) cv2.createTrackbar("G", "Camera", g, 255, on_g_trackbar) cv2.createTrackbar("B", "Camera", b, 255, on_b_trackbar) # ๋ฃจํ ์์ while cap.isOpened(): ret, frame = cap.read() if not ret: print("Can't receive frame (stream end?). Exiting ...") break # ํ ์คํธ ์ถ๋ ฅ (ํธ๋๋ฐ์์ ๋ฐ์์จ bold, color ๊ฐ ์ฌ์ฉ) cv2.putText(frame, "hhhong", topLeft, cv2.FONT_HERSHEY_SIMPLEX, 2, (b, g, r), # BGR 1 + bold) # ํ๋ ์ ์ถ๋ ฅ cv2.imshow("Camera", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break # ์ข ๋ฃ ์ฒ๋ฆฌ cap.release() cv2.destroyAllWindows() โ Quiz: Trackbar 1. Trackbar๋ฅผ controlํด์ TEXT์ ๊ตต๊ธฐ๊ฐ ๋ณํ๋ ๊ฒ์ ํ์ธํด ๋ณด์. 2. Trackbar๋ฅผ ์ถ๊ฐํด์ font size๋ฅผ ๋ณ๊ฒฝ / ์ ์ฉํด ๋ณด์. 3. R/G/B Trackbar๋ฅผ ๊ฐ๊ฐ ์ถ๊ฐํด์ ๊ธ์์ font color๋ฅผ ๋ณ๊ฒฝํด ๋ณด์.
Study
ยท 2025-06-24
Day1 : Linux start
๐ 1. ๋ฆฌ๋ ์ค ์์คํ ๊ธฐ๋ณธ ๋ช ๋ น์ด ctrl + alt + T : ํฐ๋ฏธ๋์ ์ ์ฐฝ์ผ๋ก ์คํ python3 : Python 3 ๋ฒ์ ํ์ธ (์: 3.10.12) df -h : ๋์คํฌ ํํฐ์ ์ฌ์ฉ๋ ํ์ธ (์ฌ์ด์ฆ ๋จ์ human-readable) ifconfig : IP ์ฃผ์ ๋ฐ ๋คํธ์ํฌ ์ ๋ณด ํ์ธ (net-tools ํ์) htop : CPU ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ค์๊ฐ ๋ชจ๋ํฐ๋ง clear : ํฐ๋ฏธ๋ ํ๋ฉด์ ๊นจ๋ํ๊ฒ ์ง์ echo : ๋ฌธ์์ด์ด๋ ๋ณ์ ๊ฐ์ ์ถ๋ ฅ (์คํฌ๋ฆฝํธ ๋๋ฒ๊น ์ ์์ฃผ ์ฌ์ฉ) uname -a : ์ปค๋ ๋ฐ ์์คํ ์ ๋ณด ์ ์ฒด ์ถ๋ ฅ sudo : ๊ด๋ฆฌ์ ๊ถํ(superuser)์ผ๋ก ๋ช ๋ น์ด ์คํ ๐งฐ 2. ํจํค์ง ์ค์น ๋ฐ ํ๊ฒฝ ๊ตฌ์ฑ sudo apt install python3-venv : venv ๋ชจ๋ ์ค์น sudo apt install net-tools htop : ifconfig์ htop ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ํจํค์ง ์ค์น sudo apt install vim : vim ํ ์คํธ ํธ์ง๊ธฐ ์ค์น sudo apt install curl : URL ํต์ ๋๊ตฌ curl ์ค์น sudo apt install plocate : locate ๋ช ๋ น์ด ๋์ฒด ํจํค์ง ์ค์น sudo apt install ncal : ๋ฌ๋ ฅ ์ถ๋ ฅ ๋ช ๋ น์ด(ncal) ์ค์น (ํ์ฅ๋ cal) ๐ 3. Python ๊ฐ์ํ๊ฒฝ ๋ฐ pip ๊ด๋ จ ๋ช ๋ น์ด python3 -m venv .env : ๊ฐ์ ํ๊ฒฝ ์์ฑ (.env ํด๋์) source .env/bin/activate : ๊ฐ์ ํ๊ฒฝ ํ์ฑํ deactivate : ๊ฐ์ ํ๊ฒฝ ์ข ๋ฃ pip install -U pip : pip์ ์ต์ ๋ฒ์ ์ผ๋ก ์ ๊ทธ๋ ์ด๋ โ๏ธ 4. ์์คํ ์กฐ์ ๋ช ๋ น์ด ps : ํ์ฌ ์คํ ์ค์ธ ํ๋ก์ธ์ค ์ ๋ณด ํ์ธ kill : ํน์ ํ๋ก์ธ์ค๋ฅผ ์ข ๋ฃ (์: kill PID) service : ๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค ์์/์ค์ง/์ฌ์์ ๋ฑ ๊ด๋ฆฌ batch : ์์คํ ๋ถํ๊ฐ ์ ์ ๋ ๋ช ๋ น์ด๋ฅผ ์คํ (์ง์ฐ ์คํ) shutdown : ์์คํ ์ข ๋ฃ ๋๋ ์ฌ๋ถํ ์์ฝ (์: shutdown -h now) ๐ 5. ํ์ผ ๊ด๋ฆฌ ๋ช ๋ น์ด touch : ์๋ก์ด ๋น ํ์ผ ์์ฑ cat : ํ์ผ ๋ด์ฉ์ ์ถ๋ ฅํ๊ฑฐ๋ ์ฌ๋ฌ ํ์ผ์ ์ฐ๊ฒฐ head : ํ์ผ์ ์ฒ์ ๋ช ์ค์ ์ถ๋ ฅ (๊ธฐ๋ณธ 10์ค) tail : ํ์ผ์ ๋ง์ง๋ง ๋ช ์ค์ ์ถ๋ ฅ (๊ธฐ๋ณธ 10์ค) cp : ํ์ผ์ด๋ ๋๋ ํ ๋ฆฌ๋ฅผ ๋ณต์ฌ mv : ํ์ผ์ด๋ ๋๋ ํ ๋ฆฌ๋ฅผ ์ด๋ํ๊ฑฐ๋ ์ด๋ฆ ๋ณ๊ฒฝ comm : ๋ ๊ฐ์ ์ ๋ ฌ๋ ํ์ผ์ ๋น๊ตํ์ฌ ๊ณตํต/์ฐจ์ด ์ถ๋ ฅ cmp : ๋ ํ์ผ์ ๋ฐ์ดํธ ๋จ์๋ก ๋น๊ต (๋ค๋ฅธ ์์น ์ถ๋ ฅ) dd : ์ ์์ค ๋ณต์ฌ ๋ช ๋ น์ด (๋์คํฌ ๋ฐฑ์ , ISO ๊ตฝ๊ธฐ ๋ฑ ํ์ฉ๋จ) ln : ๋งํฌ ํ์ผ ์์ฑ (๊ธฐ๋ณธ์ ํ๋๋งํฌ, `-s`๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ) less : ๊ธด ํ์ผ์ ํ ํ๋ฉด์ฉ ์ฝ๊ธฐ (์คํฌ๋กค ๊ฐ๋ฅ, cat๋ณด๋ค ํธํจ) sort : ํ์ผ ๋ด์ฉ์ ์ํ๋ฒณ ๋๋ ์ซ์ ์์ผ๋ก ์ ๋ ฌ chmod : ํ์ผ ๊ถํ ์ค์ (์: ์คํ ๊ถํ ๋ถ์ฌ) chown : ํ์ผ์ด๋ ๋๋ ํ ๋ฆฌ์ ์์ ์(user)๋ ๊ทธ๋ฃน ๋ณ๊ฒฝ ๐ 6. ๋คํธ์ํฌ ๊ด๋ จ ๋ช ๋ น์ด wget : URL๋ก๋ถํฐ ํ์ผ ๋ค์ด๋ก๋ (์: ์ด๋ฏธ์ง, ๋ฌธ์ ๋ฑ) curl : URL๋ก๋ถํฐ ๋ฐ์ดํฐ ์ ์ก ๋๋ ์์ (API ํ ์คํธ์ ์์ฃผ ์ฌ์ฉ) traceroute : ๋ชฉ์ ์ง๊น์ง ๊ฑฐ์น๋ ๋ผ์ฐํฐ ๊ฒฝ๋ก ์ถ์ (๋คํธ์ํฌ ๋ฌธ์ ์ง๋จ์ ์ฌ์ฉ) iptables : ๋ฆฌ๋ ์ค ๋ฐฉํ๋ฒฝ ์ค์ ๋ฐ ํจํท ํํฐ๋ง ์ ์ด ๐ 7. ๊ฒ์ ๋ฐ ์ ๊ท ํํ์ find : ํ์ผ์ด๋ ๋๋ ํ ๋ฆฌ๋ฅผ ์กฐ๊ฑด ๊ธฐ์ค์ผ๋ก ๊ฒ์ which : ๋ช ๋ น์ด์ ์คํ ํ์ผ ๊ฒฝ๋ก ํ์ธ (PATH์์ ๊ฒ์) locate : ์ธ๋ฑ์ค ๊ธฐ๋ฐ์ผ๋ก ๋น ๋ฅด๊ฒ ํ์ผ ๊ฒฝ๋ก ๊ฒ์ (`updatedb` ํ์) grep : ํ ์คํธ์์ ํน์ ๋ฌธ์์ด ๊ฒ์ ๋ฐ ์ถ๋ ฅ (์ ๊ท ํํ์ ์ง์) sed : ๋ฌธ์์ด ์นํ/์ญ์ ๋ฑ ์คํธ๋ฆผ ํธ์ง์ ์ฌ์ฉ ๐งฉ 8. ๊ธฐํ ๋ช ๋ น์ด man : ๋ช ๋ น์ด ์ฌ์ฉ๋ฒ, ์ต์ ๋ฑ์ ์ค๋ช ํ๋ ๋งค๋ด์ผ ํ์ด์ง ๋ณด๊ธฐ whatis : ๋ช ๋ น์ด์ ์งง์ ์ค๋ช ์ถ๋ ฅ (man ํ์ด์ง ์์ฝ) cal : ์๊ฐ ๋ฌ๋ ฅ ์ถ๋ ฅ (์: cal 2025 6) banner : ์ ๋ ฅํ ๋ฌธ์์ด์ ํฐ ์์คํค ์ํธ ํ ์คํธ๋ก ์ถ๋ ฅ rev : ๋ฌธ์์ด์ด๋ ํ์ผ ๋ด์ฉ์ ๋ฐ๋๋ก ์ถ๋ ฅ tar : ํ์ผ ๋ฐ ๋๋ ํ ๋ฆฌ๋ฅผ ์์นด์ด๋ธํ๊ฑฐ๋ ์์ถ ํด์ ๐ 9. Vim ํ์ ๋ฐ ๊ฒ์ ๋จ์ถํค Shift + G : ํ์ผ์ ๋ง์ง๋ง ์ค๋ก ์ด๋ /๋ฌธ์์ด : ๋ฌธ์์ด ๊ฒ์ (์: /pip) n : ๋ค์ ๊ฒ์ ๊ฒฐ๊ณผ๋ก ์ด๋ N : ์ด์ ๊ฒ์ ๊ฒฐ๊ณผ๋ก ์ด๋ ๐ก 10. ๋ฉ๋ชจ Ctrl + w + v : Vim์์ ์์ง ์ฐฝ ๋ถํ :e . : Vim์์ ํ์ผ ํ์๊ธฐ ์ด๊ธฐ locate python3 > search.txt : locate ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅ grep -rn 'pip' > result.txt : ํ์ฌ ๋๋ ํ ๋ฆฌ ๋ด 'pip' ํฌํจ ์ค์ ์ฌ๊ท์ ์ผ๋ก ๊ฒ์ํด ์ ์ฅ # Home Work ํฐ ๋ ธ์ด๋ง ์ํคํ ์ฒ ํฐ ๋ ธ์ด๋ง ๋ณ๋ชฉ ํ์ ์บ์ ๋ฉ๋ชจ๋ฆฌ ํ๋ฒ๋ ์ํคํ ์ฒ ํ์ดํ๋ผ์ด๋ ๋ฉํฐ์ฝ์ด ํ๋ก์ธ์ ๊ตฌ๊ธ ์ ๋ฏธ๋์ด: PPT ์ ์ ์ฉ์ด (.html)
Study
ยท 2025-06-23
<
>
Touch background to close