728x90

2023-11-22 55th Class

MNIST DETAILS

#️⃣ Base Code

from torchvision.datasets import MNIST  
import numpy as np  
  
  
dataset = MNIST(root='data', train=True, download=True)  
  
for img, label in dataset:  
    print(type(img))  
    print(type(label))  
    img.show()  
    img = np.array(img)  
    print(img.shape, img.dtype)  
    # uint8 unsigned integer 8 bit  
    break

'''
<class 'PIL.Image.Image'>
<class 'int'>
(28, 28) uint8
'''
  • uint8: unsigned integer 8 bit
  • MNIST 데이터는 28x28 의 이미지가 unsigned integer 8 bit 타입
  • feature가 28x28=784 개인 데이터
def show_mnist_img():  
    dataset = MNIST(root='data', train=True, download=True)  
  
    fig, axes = plt.subplots(2, 5, figsize=(10, 5))  
    axes = axes.flatten()  
  
    for i, (img, label) in enumerate(dataset):  
        print(type(img))  
        print(type(label))  
        # img.show()  
        axes[i].imshow(img, cmap="gray")  
        axes[i].axis("off")  
        axes[i].set_title(f"Class {label}", fontsize=15)  
        img = np.array(img)  
        print(img.shape, img.dtype) # uint8 unsigned integer 8 bit  
  
        if i == 9:  
            break  
  
    fig.tight_layout()  
    plt.show()  
  
show_mnist_img()

231122 mnistimgs.png|700

0~255에서 -> float 32로 변환

code (교안 코드)

class MNIST_Classifier(nn.Module):  
    def __init__(self):  
        super(MNIST_Classifier, self).__init__()  
  
        self.fc1 = nn.Linear(in_features=784, out_features=512)  
        self.fc1_act = nn.ReLU()  
  
        self.fc2 = nn.Linear(in_features=512, out_features=128)  
        self.fc2_act = nn.ReLU()  
  
        self.fc3 = nn.Linear(in_features=128, out_features=52)  
        self.fc3_act = nn.ReLU()  
  
        self.fc4 = nn.Linear(in_features=52, out_features=10)  
  
    def forward(self, x):  
        x = self.fc1_act(self.fc1(x))  
        x = self.fc2_act(self.fc2(x))  
        x = self.fc3_act(self.fc3(x))  
        x = self.fc4(x)  
        return x  
  
  
def plot_metrics(losses, accs):  
    fig, axes = plt.subplots(2, 1, figsize=(10, 5))  
  
    axes[0].plot(losses)  
    axes[1].plot(accs)  
  
    axes[1].set_xlabel("Epoch", fontsize=15)  
    axes[0].set_ylabel("Loss", fontsize=15)  
    axes[1].set_ylabel("Accuracy", fontsize=15)  
    axes[0].tick_params(labelsize=10)  
    axes[1].tick_params(labelsize=10)  
    fig.suptitle("MNIST 4-layer Model Metrics by Epoch", fontsize=16)  
    plt.show()  
  
  
def mnist_main_routine():  
    BATCH_SIZE = 32  
    LR = 0.003  
    EPOCHS = 10  
  
    dataset = MNIST(root='data', train=True, download=True, transform=ToTensor())  
    n_samples = len(dataset)  
  
    DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')  
    print(f"{DEVICE=}")  
    model = MNIST_Classifier().to(DEVICE)  
    loss_function = nn.CrossEntropyLoss()  
    optimizer = SGD(model.parameters(), lr=LR)  
    dataloader = DataLoader(dataset, batch_size=BATCH_SIZE)  
  
    losses, accs = [], []  
    for epoch in range(EPOCHS):  
        epoch_loss, n_corrects = 0., 0  
  
        for X_, y_ in tqdm(dataloader):  
            X_, y_ = X_.to(DEVICE), y_.to(DEVICE)  
            X_ = X_.reshape(BATCH_SIZE, -1)  
  
            pred = model(X_)  
            loss = loss_function(pred, y_)  
  
            optimizer.zero_grad()  
            loss.backward()  
            optimizer.step()  
  
            epoch_loss += loss.item() * len(X_)  
            n_corrects += (torch.max(pred, dim=1)[1] == y_).sum().item()  
  
        epoch_loss /= n_samples  
        losses.append(epoch_loss)  
  
        epoch_acc = n_corrects / n_samples  
        accs.append(epoch_acc)  
  
        print(f"Epoch: {epoch+1}", end="\t")  
        print(f"Loss: {epoch_loss:.4f} - Acc: {epoch_acc:.4f}")  
  
    plot_metrics(losses, accs)  
  
  
if __name__ == '__main__':  
    mnist_main_routine()

231122 mnist_vis.png

DEVICE=device(type='cuda')
100%|██████████| 1875/1875 [00:05<00:00, 338.23it/s]
Epoch: 1	Loss: 2.2640 - Acc: 0.2625
100%|██████████| 1875/1875 [00:04<00:00, 411.36it/s]
Epoch: 2	Loss: 1.8118 - Acc: 0.4707
100%|██████████| 1875/1875 [00:04<00:00, 397.89it/s]
  0%|          | 0/1875 [00:00<?, ?it/s]
Epoch: 3	Loss: 0.8574 - Acc: 0.7551
100%|██████████| 1875/1875 [00:04<00:00, 394.04it/s]
  0%|          | 0/1875 [00:00<?, ?it/s]
Epoch: 4	Loss: 0.5439 - Acc: 0.8407
100%|██████████| 1875/1875 [00:04<00:00, 394.30it/s]
  0%|          | 0/1875 [00:00<?, ?it/s]
Epoch: 5	Loss: 0.4437 - Acc: 0.8722
100%|██████████| 1875/1875 [00:04<00:00, 393.17it/s]
  0%|          | 0/1875 [00:00<?, ?it/s]
Epoch: 6	Loss: 0.3881 - Acc: 0.8895
100%|██████████| 1875/1875 [00:04<00:00, 393.66it/s]
  0%|          | 0/1875 [00:00<?, ?it/s]
Epoch: 7	Loss: 0.3500 - Acc: 0.9008
100%|██████████| 1875/1875 [00:04<00:00, 390.45it/s]
Epoch: 8	Loss: 0.3214 - Acc: 0.9090
100%|██████████| 1875/1875 [00:04<00:00, 392.98it/s]
Epoch: 9	Loss: 0.2976 - Acc: 0.9155
100%|██████████| 1875/1875 [00:04<00:00, 407.65it/s]
Epoch: 10	Loss: 0.2764 - Acc: 0.9215
2023-11-22T02:20:56.554ZE [1012:NonCelloThread] thumbnail_util_win.cc:45:DecodePng Can't decode PNG: 0x88982F04
2023-11-22T02:20:56.554ZE [1012:NonCelloThread] thumbnail_util_win.cc:100:ConvertImageBufferToBitmap Can't decode PNG.


Pattern in Numpy

#️⃣ Pattern Image

code

import numpy as np  
import matplotlib.pyplot as plt  
  
'''np.ones: 입력된 shape의 array를 만들고, 모두 1로 채워주는 함수'''  
  
tmp = np.ones(shape=(2, 3))  
# (2, 3)의 shape를 가지고 모두 1로 채워져있는 행렬을 만들어라  
print(tmp)  

'''
[[1. 1. 1.]
 [1. 1. 1.]]
'''
  
'''ndarray에 scalar를 곱하면 원소별 곱셈'''  
tmp2 = 10 * tmp  
print(tmp2)
'''
[[10. 10. 10.]
 [10. 10. 10.]]
'''

check patttern

def check_pattern_image():  
    white_patch = 255 * np.ones(shape=(10, 10))  
    black_patch = 0 * np.ones(shape=(10, 10))  
  
    img1 = np.hstack([white_patch, black_patch]) # [흰, 검] (10, 20)  
    img2 = np.hstack([black_patch, white_patch]) # [검, 흰] (10, 20)  
    img = np.vstack([img1, img2])  
  
    fig, ax = plt.subplots(figsize=(4, 4))  
    ax.imshow(img, cmap='gray')  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
  
    plt.show()  
  
  
def check_pattern_image2():  
    white_patch = 255 * np.ones(shape=(10, 10))  
    black_patch = np.zeros(shape=(10, 10))  
  
    img1 = np.hstack([white_patch, black_patch, white_patch])  
    img2 = np.hstack([black_patch, white_patch, black_patch])  
    img = np.vstack([img1, img2, img1])  
  
    fig, ax = plt.subplots(figsize=(4, 4))  
    ax.imshow(img, cmap='gray')  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
  
    plt.show()

'''

check_pattern_image() check_pattern_image2()
231122-2 check pattern image.png 231122-2 check pattern image2.png
  • 색상표 기준으로 0(흰색) ~ 255(검은색)으로 환산됨
  • 255 = 흰색
  • 0 = 검은색

np.repeat & np.tile 기본

def repeat_tile():  
    data = np.arange(5)  
    print(data)  
  
    # np.repeat => 원소별 반복  
    print("repeat:", np.repeat(data, repeats=3))  
  
    # np.tile => 전체 반복  
    print("tile:", np.tile(data, reps=3))

'''
[0 1 2 3 4]
repeat: [0 0 0 1 1 1 2 2 2 3 3 3 4 4 4]
tile: [0 1 2 3 4 0 1 2 3 4 0 1 2 3 4]
'''

np.repeat

def repeat2():  
    data = np.arange(6).reshape(2, 3)  
    print(data)  
  
    print(f"repeats=3, axis=0 \n {np.repeat(data, repeats=3, axis=0)}")  
    print(f"repeats=3, axis=1 \n {np.repeat(data, repeats=3, axis=1)}")  
    print(f"np.repeat(np.repeat(data, repeats=2, axis=0), repeats=3, axis=1) \n {np.repeat(np.repeat(data, repeats=2, axis=0), repeats=3, axis=1)}")

'''
[[0 1 2]
 [3 4 5]]
repeats=3, axis=0 
 [[0 1 2]
 [0 1 2]
 [0 1 2]
 [3 4 5]
 [3 4 5]
 [3 4 5]]
repeats=3, axis=1 
 [[0 0 0 1 1 1 2 2 2]
 [3 3 3 4 4 4 5 5 5]]
np.repeat(np.repeat(data, repeats=2, axis=0), repeats=3, axis=1) 
 [[0 0 0 1 1 1 2 2 2]
 [0 0 0 1 1 1 2 2 2]
 [3 3 3 4 4 4 5 5 5]
 [3 3 3 4 4 4 5 5 5]]
'''

np.tile

def tile2():  
    data = np.arange(6).reshape(2, 3)  
    print(data)  
  
    print("tile(axis=0)")  
    print(np.tile(data, reps=[3, 1]))  
    print("tile(axis=1)")  
    print(np.tile(data, reps=[1, 3]))  
    print("tile(axis=0 and axis=1)")  
    print(np.tile(data, reps=[3, 3]))

'''
[[0 1 2]
 [3 4 5]]
tile(axis=0)
[[0 1 2]
 [3 4 5]
 [0 1 2]
 [3 4 5]
 [0 1 2]
 [3 4 5]]
tile(axis=1)
[[0 1 2 0 1 2 0 1 2]
 [3 4 5 3 4 5 3 4 5]]
tile(axis=0 and axis=1)
[[0 1 2 0 1 2 0 1 2]
 [3 4 5 3 4 5 3 4 5]
 [0 1 2 0 1 2 0 1 2]
 [3 4 5 3 4 5 3 4 5]
 [0 1 2 0 1 2 0 1 2]
 [3 4 5 3 4 5 3 4 5]]
'''

check pattern image with np.tile()

def check_pattern_image_w_nptile():  
    white_patch = 255 * np.ones(shape=(10, 10))  
    black_patch = np.zeros(shape=(10, 10))  
  
    img1 = np.hstack([white_patch, black_patch])  
    img2 = np.hstack([black_patch, white_patch])  
    img = np.vstack([img1, img2])  
  
    tile = np.tile(img, reps=[4, 4])  
    fig, ax = plt.subplots(figsize=(5, 5))  
    ax.imshow(tile, cmap='gray')  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    plt.show()

def check_pattern_image_w_nptile2():  
    white_patch = 255 * np.ones(shape=(10, 10))  
    gray_patch = int(255/2) * np.ones(shape=(10, 10))  
    black_patch = np.zeros(shape=(10, 10))  
  
    img1 = np.hstack([white_patch, gray_patch])  
    img2 = np.hstack([gray_patch, black_patch])  
    img = np.vstack([img1, img2])  
  
    tile = np.tile(img, reps=[4, 4])  
    fig, ax = plt.subplots(figsize=(5, 5))  
    ax.imshow(tile, cmap='gray')  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    plt.show()
check_pattern_image_w_nptile() check_pattern_image_w_nptile2()
231122-3 tilepattern.png 231122-3 tilepattern2.png

grayscale_gradation_image_with_nprepeat

def grayscale_gradation_image_with_nprepeat():  
    img = np.arange(0, 256, 50).reshape(1, -1)  
    img = img.repeat(100, axis=0).repeat(30, axis=1)  
  
    fig, ax = plt.subplots(figsize=(4, 2))  
    ax.imshow(img, cmap='gray')  
  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    plt.show()  
  
  
def grayscale_gradation_image_with_nprepeat2():  
    max_num = 151 # 256  
    # n = int(max_num/4)    
    img = np.arange(0, max_num, 50).reshape(1, -1)  
    img = img.repeat(100, axis=0).repeat(30, axis=1)  
  
    fig, ax = plt.subplots(figsize=(4, 2))  
    ax.imshow(img, cmap='gray', vmax=255, vmin=0)  
  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    plt.show()  
  
  
def grayscale_gradation_image_with_nprepeat3():  
    img = np.arange(0, 256, 50)[::-1].reshape(-1, 1)  
    # img = np.arange(256, 0, -50).reshape(-1, 1)  
    img = img.repeat(30, axis=0).repeat(100, axis=1)  
  
    fig, ax = plt.subplots(figsize=(2, 4))  
    ax.imshow(img, cmap='gray', vmax=256, vmin=0)  
  
    ax.tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    plt.show()  
  
  
def grayscale_gradation_image_with_nprepeat4():  
    img1 = np.arange(0, 256, 2).reshape(1, -1)  
    img1 = img1.repeat(100, axis=0)  
    img1 = img1.repeat(2, axis=1)  
  
    img2 = np.arange(0, 256, 2)[::-1].reshape(1, -1)  
    img2 = img2.repeat(100, axis=0).repeat(2, axis=1)  
  
    fig, axes = plt.subplots(2, 1, figsize=(5, 5))  
    axes[0].imshow(img1, cmap='gray', vmax=256, vmin=0)  
    axes[1].imshow(img2, cmap='gray', vmax=256, vmin=0)  
  
    axes[0].tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
    axes[1].tick_params(left=False, labelleft=False, bottom=False, labelbottom=False)  
  
    fig.tight_layout()  
    plt.show()

grayscale_gradation_image_with_nprepeat4():

231122-4 gradient.png


Sobel Filtering

#️⃣ 1-Dimensional Window Extraction

window란 시퀀스 데이터에서 일정한 크기의 부분 데이터를 의미함
예를들어, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10의 연속 데이터에서 윈도우 사이즈가 3이면
123 234 345 456 567 678 789 8910으로 데이터를 관찰함

윈도우 사이즈는 홀수 여야 함
(중심점이 있어야 하기 때문)

window의 개수 (L’) = L - W + 1
l : 데이터 전체 길이
w : window 길이

def one_dimensional_window_extraction():  
    data = 10 * np.arange(1, 11)  
    window_size = 3  
    n_window = len(data) - window_size + 1  
    print(f"{n_window=}")  
  
    extracted = [data[i:i+window_size] for i in range(n_window)]  
    print(extracted)

'''
n_window=8
[array([10, 20, 30]), array([20, 30, 40]), array([30, 40, 50]), array([40, 50, 60]), array([50, 60, 70]), array([60, 70, 80]), array([70, 80, 90]), array([ 80,  90, 100])]
'''

#️⃣ 2-Dimensional Window Extraction

2차원 데이터의 window는 NxN으로 CNN의 커널과 같은 역할을 함

  • 위쪽의 초록색은 3x3 window
  • 아래쪽의 파란색은 5x5 data
  • 빈 공간은 padding이나 현재는 무시하고 파란색 영역 안에서만 이동
  • 위와 같이 데이터에서 커널 사이즈만큼 추출
10 20 30 40 50 60 70
20 30 40 50 60 70 80
30 40 50 60 70 80 90
40 50 60 70 80 90 100
50 60 70 80 90 100 110

1st
[ 10 20 30 ]
[ 20 30 40 ]
[ 30 40 50 ]

2nd
[ 20 30 40]
[ 30 40 50]
[ 40 50 60]

n x n 칸씩 이동

def two_dimensional_window_extraction():  
    rows = np.arange(1, 6).reshape(-1, 1)  
    cols = np.arange(7)  
    data = (rows + cols) * 10  
  
    window_size = 3  
    height, width = data.shape  
    n_window_height = height - window_size + 1  
    n_window_width = width - window_size + 1  
    print(f"{n_window_height=}, {n_window_width=}")  
  
    extracted = np.array([[data[row:row+window_size, col:col+window_size] for col in range(n_window_width)] for row in range(n_window_height)])  
    print(f"{extracted.shape=} => 3x3 커널이 3x5=15개")  
    print(extracted)
n_window_height=3, n_window_width=5
extracted.shape=(3, 5, 3, 3) => 3x3 커널이 3x5=15개
[[[[ 10  20  30]
   [ 20  30  40]
   [ 30  40  50]]

  [[ 20  30  40]
   [ 30  40  50]
   [ 40  50  60]]

  [[ 30  40  50]
   [ 40  50  60]
   [ 50  60  70]]

  [[ 40  50  60]
   [ 50  60  70]
   [ 60  70  80]]

  [[ 50  60  70]
   [ 60  70  80]
   [ 70  80  90]]]


 [[[ 20  30  40]
   [ 30  40  50]
   [ 40  50  60]]

  [[ 30  40  50]
   [ 40  50  60]
   [ 50  60  70]]

  [[ 40  50  60]
   [ 50  60  70]
   [ 60  70  80]]

  [[ 50  60  70]
   [ 60  70  80]
   [ 70  80  90]]

  [[ 60  70  80]
   [ 70  80  90]
   [ 80  90 100]]]


 [[[ 30  40  50]
   [ 40  50  60]
   [ 50  60  70]]

  [[ 40  50  60]
   [ 50  60  70]
   [ 60  70  80]]

  [[ 50  60  70]
   [ 60  70  80]
   [ 70  80  90]]

  [[ 60  70  80]
   [ 70  80  90]
   [ 80  90 100]]

  [[ 70  80  90]
   [ 80  90 100]
   [ 90 100 110]]]]
반응형