1. 텐서플로우
텐서플로우(TensorFlow)는 구글에서 개발한 오픈소스 머신러닝 라이브러리로, 수치 계산과 딥러닝 모델 구축을 위한 강력한 기능을 제공합니다. 데이터 흐름 그래프(Data Flow Graph)를 기반으로 작동하며, 노드(Node)는 연산을, 엣지(Edge)는 다차원 배열인 텐서(Tensor)를 나타냅니다. CPU, GPU, TPU 등 다양한 하드웨어에서 효율적으로 작동하며, 특히 대규모 신경망 학습과 추론에 적합합니다. 텐서플로우는 파이썬을 주로 사용하며, 직관적인 고수준 API인 Keras를 포함하고 있어 모델을 쉽고 빠르게 구축할 수 있는 환경을 제공합니다.
1. 텐서란?
TensorFlow에서의 텐서(Tensor)는 다차원 배열을 표현하는 핵심 데이터 구조로, 기능적으로는 파이썬의 넘파이(NumPy) 배열과 매우 유사합니다. 그러나 단순한 배열을 넘어서, 텐서는 딥러닝 모델 학습에 필수적인 자동 미분(automatic differentiation) 기능을 지원하며, 이를 통해 모델 학습 시 역전파(backpropagation)를 자동으로 처리할 수 있습니다. 텐서는 GPU나 TPU와 같은 다양한 장치에서 효율적으로 계산될 수 있도록 설계되어 있으며, 다음과 같은 기본 속성을 가집니다:
- 모양(shape): 텐서가 가지는 차원의 크기를 나타내며, 예를 들어 (3, 4)는 3행 4열의 2차원 텐서를 의미합니다.
- 자료형(data type): 텐서에 저장되는 데이터의 타입으로, float32, int32 등 다양한 타입이 있습니다.
- 저장된 장치(device): 텐서가 현재 어느 하드웨어(CPU, GPU 등)에 저장되어 있는지를 나타냅니다.
data = [
[1, 2],
[3, 4]
]
x = tf.constant(data)
print(x)
print(tf.rank(x)) # 차원 출력
data = tf.constant("String")
print(data)
a = tf.constant([5])
b = tf.constant([7])
c = (a + b).numpy()
print(c)
print(type(c))
result = c * 10
tensor = tf.convert_to_tensor(result)
print(tensor)
print(type(tensor))
EagerTensor
EagerTensor는 TensorFlow에서 연산이 즉시 실행되는 방식인 Eager Execution 모드에서 생성되는 텐서입니다.
기존의 TensorFlow 1.x에서는 연산을 그래프로 정의한 후, Session을 통해 실행해야 했지만, TensorFlow 2.x부터는 즉시 실행(Eager Execution)이 기본값으로 활성화되어, Python 코드처럼 한 줄 한 줄 바로 계산 결과를 확인할 수 있게 되었습니다.
x = tf.constant([
[5, 7],
[1, 2]
])
# x와 같은 모양과 자료형을 가지지만, 값이 1인 텐서 생성
x_ones = tf.ones_like(x)
print(x_ones)
# x와 같은 모양을 가지되, 자료형은 float, 값은 랜덤으로 채우기
x_rand = tf.random.uniform(shape=x.shape, dtype=tf.float32) # uniform distribution [0, 1)
print(x_rand)
2. 텐서의 형변환 및 차원 조작
tensor = tf.constant([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
print(tensor[0]) # first row
print(tensor[:, 0]) # first column
print(tensor[..., -1]) # last column
tensor = tf.constant([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
# axis: 텐서를 이어 붙이기 위한 축
# 0번 축(행)을 기준으로 이어 붙이기
result = tf.concat([tensor, tensor, tensor], axis=0)
print(result)
# 1번 축(열)을 기준으로 이어 붙이기
result = tf.concat([tensor, tensor, tensor], axis=1)
print(result)
a = tf.constant([2])
b = tf.constant([5.0])
print(a.dtype)
print(b.dtype)
# 텐서 a를 float32 형식으로 변경한 뒤에 더하기 수행
print(tf.cast(a, tf.float32) + b)
a = tf.constant([2])
b = tf.constant([5.0])
print(a.dtype)
print(b.dtype)
# 텐서 a를 float32 형식으로 변경한 뒤에 더하기 수행
print(tf.cast(a, tf.float32) + b)
a = tf.Variable([1, 2, 3, 4, 5, 6, 7, 8])
b = tf.reshape(a, (4, 2))
print(b)
# a와 b는 서로 다른 객체
a.assign_add([1, 1, 1, 1, 1, 1, 1, 1])
print(a)
print(b)
a = tf.random.uniform((64, 32, 3))
print(a.shape)
b = tf.transpose(a, perm=[2, 1, 0]) # 차원 자체를 교환
# (2번째 축, 1번째 축, 0번째 축)의 형태가 되도록 한다.
print(b.shape)
3. 텐서의 연산과 함수
a = tf.constant([
[1, 2],
[3, 4]
])
b = tf.constant([
[5, 6],
[7, 8]
])
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(tf.matmul(a, b))
a = tf.constant([
[1, 2, 3, 4],
[5, 6, 7, 8]
])
print(a)
print(tf.reduce_mean(a)) # 전체 원소에 대한 평균
print(tf.reduce_mean(a, axis=0)) # 각 열에 대하여 평균 계산
print(tf.reduce_mean(a, axis=1)) # 각 행에 대하여 평균 계산
print(tf.reduce_sum(a)) # 전체 원소에 대한 합계
print(tf.reduce_sum(a, axis=0)) # 각 열에 대하여 합계 계산
print(tf.reduce_sum(a, axis=1)) # 각 행에 대하여 합계 계산
print(tf.reduce_max(a)) # 전체 원소에 대한 최댓값
print(tf.reduce_max(a, axis=0)) # 각 열에 대하여 최댓값 계산
print(tf.reduce_max(a, axis=1)) # 각 행에 대하여 최댓값 계산
print(tf.argmax(a, axis=0)) # 각 열에 대하여 최댓값의 인덱스 계산
print(tf.argmax(a, axis=1)) # 각 행에 대하여 최댓값의 인덱스 계산
print(a.shape)
# 첫 번째 축에 차원 추가
a = tf.expand_dims(a, 0)
print(a)
print(a.shape)
# 네 번째 축에 차원 추가
a = tf.expand_dims(a, 3)
print(a)
print(a.shape)
# 크기가 1인 차원 제거
a = tf.squeeze(a)
print(a)
print(a.shape)
4. 자동 미분과 기울기
x = tf.Variable([3.0, 4.0])
y = tf.Variable([1.0, 2.0])
# 진행되는 모든 연산들을 기록
with tf.GradientTape() as tape:
z = x + y
loss = tf.math.reduce_mean(z)
dx = tape.gradient(loss, x) # loss가 scalar이므로 계산 가능
print(dx)
x = tf.linspace(-10, 10, 100)
with tf.GradientTape() as tape:
tape.watch(x) # constant이므로, watch() 함수 호출 필요
y = tf.nn.sigmoid(x)
dx = tape.gradient(y, x)
print(dx)
import matplotlib.pyplot as plt
plt.plot(x, y, 'r', label="y")
plt.plot(x, dx, 'b--', label="dy/dx")
plt.legend()
plt.show()
2. 모델 만들기
from google.colab import files
files.upload() # kaggle.json 업로드 창 표시
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
!kaggle datasets download pratik2901/multiclass-weather-dataset
import os
import zipfile
import random
from shutil import copyfile, rmtree
zip_file = 'multiclass-weather-dataset.zip'
base_dir = './Multi-class Weather Dataset'
train_dir = './train'
test_dir = './test'
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
zip_ref.extractall('.') # 현재 디렉토리에 압축해제
# 분류 디렉터리 목록
categories = ['Cloudy', 'Rain', 'Shine', 'Sunrise']
if os.path.exists(train_dir):
rmtree(train_dir)
if os.path.exists(test_dir):
rmtree(test_dir)
# train, test 폴더 및 하위 카테고리 폴더 생성
os.makedirs(train_dir, exist_ok=True)
os.makedirs(test_dir, exist_ok=True)
for category in categories:
os.makedirs(os.path.join(train_dir, category), exist_ok=True)
os.makedirs(os.path.join(test_dir, category), exist_ok=True)
base_dir = '/content/Multi-class Weather Dataset'
# 각 카테고리별 데이터 파일 나누기
for category in categories:
category_path = os.path.join(base_dir, category)
files = os.listdir(category_path)
# 데이터 섞기
random.shuffle(files)
# 데이터 나누기 (8:2 비율)
split_idx = int(len(files) * 0.8)
train_files = files[:split_idx]
test_files = files[split_idx:]
# 파일 복사
for file in train_files:
src = os.path.join(category_path, file)
dst = os.path.join(train_dir, category, file)
copyfile(src, dst)
for file in test_files:
src = os.path.join(category_path, file)
dst = os.path.join(test_dir, category, file)
copyfile(src, dst)
print("데이터 분리가 완료되었습니다.")
from tensorflow.keras.models import Sequential
from tensorflow.keras import layers
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras import optimizers
import numpy as np
import matplotlib.pyplot as plt
train_generator = ImageDataGenerator(
rescale=1/255.,
horizontal_flip=True,
validation_split=0.2
)
test_generator = ImageDataGenerator(rescale=1/255.)
train_flow = train_generator.flow_from_directory(
directory='train/',
shuffle=True,
target_size=(224, 224),
class_mode='categorical',
batch_size=64,
subset="training"
)
val_flow = train_generator.flow_from_directory(
directory='train/',
shuffle=False,
target_size=(224, 224),
class_mode='categorical',
batch_size=64,
subset="validation"
)
test_flow = test_generator.flow_from_directory(
directory='test/',
shuffle=False,
target_size=(224, 224),
class_mode='categorical',
batch_size=64
)
plt.rcParams['figure.figsize'] = [12, 8]
plt.rcParams['figure.dpi'] = 60
plt.rcParams.update({'font.size': 20})
class_names = {
0: "Cloudy",
1: "Rain",
2: "Shine",
3: "Sunrise"
}
images, targets = next(train_flow)
print([class_names[x] for x in np.argmax(targets[:4], axis=1)])
plt.imshow(np.concatenate((images[0], images[1], images[2], images[3]), axis=1))
plt.show()
def get_model_1():
model = Sequential()
model.add(layers.Input(shape=(224, 224, 3)))
model.add(layers.Flatten()) # dimension: 224 * 224 * 3
model.add(layers.Dense(4, activation="softmax"))
return model
def get_model_2():
model = Sequential()
model.add(layers.Input(shape=(224, 224, 3)))
model.add(layers.Flatten()) # dimension: 224 * 224 * 3
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(4, activation="softmax"))
return model
def get_model_3():
model = Sequential()
model.add(layers.Input(shape=(224, 224, 3)))
model.add(layers.Flatten()) # dimension: 224 * 224 * 3
model.add(layers.Dense(128, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(32, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(4, activation="softmax"))
return model
model_1 = get_model_1()
model_1.summary()
learning_rate = 0.01
# 학습 준비 단계(compile)
model_1.compile(
optimizer=optimizers.SGD(learning_rate=learning_rate), # 수정된 부분
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 학습 수행
history = model_1.fit(
train_flow,
epochs=20,
validation_data=val_flow
)
# 정확도 그래프
import matplotlib.pyplot as plt
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.title('Accuracy')
plt.legend(['train', 'valid'])
plt.show()
# 테스트
test_history = model_1.evaluate(test_flow)
test_loss, test_accuracy = test_history
print(f"Test loss: {test_loss:.8f}")
print(f"Test accuracy: {test_accuracy * 100.:.2f}%")
model_2 = get_model_2()
model_2.summary()
learning_rate = 0.01
# 학습 준비 단계(compile)
model_2.compile(
optimizer=optimizers.SGD(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 학습 수행
history = model_2.fit(
train_flow,
epochs=20,
validation_data=val_flow
)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.title('Accuracy')
plt.legend(['train', 'valid'])
plt.show()
# 학습된 모델 테스트
test_history = model_2.evaluate(test_flow)
test_loss, test_accuracy = test_history
print(f"Test loss: {test_loss:.8f}")
print(f"Test accuracy: {test_accuracy * 100.:.2f}%")
model_3 = get_model_3()
model_3.summary()
learning_rate = 0.01
# 학습 준비 단계(compile)
model_3.compile(
optimizer=optimizers.SGD(learning_rate=learning_rate),
loss='categorical_crossentropy',
metrics=['accuracy']
)
# 학습 수행
history = model_3.fit(
train_flow,
epochs=20,
validation_data=val_flow
)
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.ylabel('Accuracy')
plt.xlabel('Epochs')
plt.title('Accuracy')
plt.legend(['train', 'valid'])
plt.show()
# 학습된 모델 테스트
test_history = model_3.evaluate(test_flow)
test_loss, test_accuracy = test_history
print(f"Test loss: {test_loss:.8f}")
print(f"Test accuracy: {test_accuracy * 100.:.2f}%")'인공지능 > 딥러닝' 카테고리의 다른 글
| Surface Crack Detection 데이터셋 (3) | 2025.07.31 |
|---|---|
| Alien vs. Predator 데이터셋 (3) | 2025.07.30 |
| Alexnet 구현하기 (4) | 2025.07.30 |
| 손글씨 도형 분류 FastAPI로 서빙 (2) | 2025.07.29 |
| 손글씨 도형 분류하기 (0) | 2025.07.29 |