オッサンはDesktopが好き

自作PCや機械学習、自転車のことを脈絡無く書きます

Deep Learning: テキスト出力した学習モデルを使って、画像分類してみる

こちら*1と併せて、アップしています

import matplotlib.cm as cm
import matplotlib.pyplot as plt
import numpy as np

TEST_DATA_SIZE = 500
IMG_SIZE = 28
FILTER_SIZE = 32
IMG_SIZE_2 = 14
FILTER_SIZE_2 = 64
HIDEN_SIZE = 1024
OUTPUT_SIZE = 10

testImages = np.zeros((TEST_DATA_SIZE, IMG_SIZE*IMG_SIZE))

def read_test_data():
    fileImg = open('./data/testImage.txt', 'r')
    for i in range(TEST_DATA_SIZE):
        line = fileImg.readline()
        val = line.split(',')
        testImages[i, :] = val[1:IMG_SIZE*IMG_SIZE + 1]
        
def conv2d(x, flr):
    # padding='SAME'、stride=1を想定
    H = x.shape[0] + flr.shape[0] - 1
    W = x.shape[1] + flr.shape[1] - 1
    D = x.shape[2]
    layer = np.zeros([H, W, D])
    offset = round(flr.shape[0] / 2)
    for h in range(offset, H - offset): # height
        for w in range(offset, H - offset): # width
            for d in range(0, flr.shape[2]): # Depth
                layer[h, w, d] = x[h - offset, w - offset, d]

    tmp = 0.0
    output = np.zeros([x.shape[0], x.shape[0], flr.shape[3]])
    for k in range(0, flr.shape[3]): # number of filter
        for h in range(offset, H - offset): # height
            for w in range(offset, W - offset): # weight
                tmp = 0.0
                for i in range(-offset, offset + 1): # filter height
                    for j in range(-offset, offset + 1): # filter width
                        for l in range(0, flr.shape[2]): # filter depth
                            tmp += layer[h + i, w + j, l] * flr[i + offset, j + offset, l, k]
                output[h - offset, w - offset, k] = tmp
    return output

def relu3(input):
    output = np.zeros([input.shape[0], input.shape[1], input.shape[2]])
    for h in range(input.shape[0]):
        for w in range(input.shape[1]):
            for k in range(input.shape[2]):
                if (input[h, w, k] > 0):
                    output[h, w, k] = input[h, w, k]
                else:
                    output[h, w, k] = 0.0
    return output

def relu2(input):
    output = np.zeros([input.shape[0], input.shape[1]])
    for h in range(input.shape[0]):
        for w in range(input.shape[1]):
            if (input[h, w] > 0):
                output[h, w] = input[h, w]
            else:
                 output[h, w] = 0.0
    return output

def maxpool22(input):
    output = np.zeros([input.shape[0], input.shape[1], input.shape[2]])
    for k in range(input.shape[2]):
        h = 0
        H = 0
        while True: # height
            if (h + 1 >= input.shape[0]):
                break

            w = 0
            W = 0
            while True: # width
                if (w + 1 >= input.shape[1]):
                    break
                val = np.zeros(4)
                val[0] = input[h, w, k]
                val[1] = input[h + 1, w, k]
                val[2] = input[h, w + 1, k]
                val[3] = input[h + 1, w + 1, k]
                output[H, W, k] = max(val)
                w += 2
                W += 1

            h += 2
            H += 1
    return output

def ConnectFull(input, W, b):
    output = np.zeros([input.shape[0], W.shape[1]])
    for i in range(input.shape[0]):
        for j in range(W.shape[1]):
            output[i, j] = 0.0
            for k in range(input.shape[1]):
                output[i, j] += input[i, k] * W[k, j]
            output[i, j] += b[j]
    return output

def softmax(input):
    c = np.max(input)
    exp_a = np.exp(input - c)
    sum_exp_a = np.sum(exp_a)
    return exp_a / sum_exp_a

def reshape4(W, I, J, K, L):
    i = 0
    j = 0
    k = 0
    l = 0
    counter = 0
    reshaped = np.zeros([I, J, K, L])
    while True:
        reshaped[i, j, k, l] = W[counter]
        if (counter % (I*J*K) == (I*J*K - 1)):
            j = 0
            i = 0
            k = 0
            l += 1
        elif (counter % (I*J) == (I*J - 1)):
            j = 0
            i = 0
            k += 1
        elif (counter % J == (J - 1)):
            j = 0
            i += 1
        else:
            j += 1
        counter += 1

        if(counter == I*J*K*L):
            break
        
    return reshaped

if __name__=='__main__':

    # read image
    read_test_data()

    # read model
    W_conv1 = np.loadtxt('./model/W_conv1.txt')
    W_conv1 = reshape4(W_conv1, 5, 5, 1, FILTER_SIZE)
    b_conv1 = np.loadtxt('./model/b_conv1.txt')
    W_conv2 = np.loadtxt('./model/W_conv2.txt')
    W_conv2 = reshape4(W_conv2, 5, 5, FILTER_SIZE, FILTER_SIZE_2)
    b_conv2 = np.loadtxt('./model/b_conv2.txt')
    W_fc1 = np.loadtxt('./model/W_fc1.txt')
    W_fc1 = W_fc1.reshape([int(IMG_SIZE_2/2)*int(IMG_SIZE_2/2)*FILTER_SIZE_2, HIDEN_SIZE])
    b_fc1 = np.loadtxt('./model/b_fc1.txt')
    W_fc2 = np.loadtxt('./model/W_fc2.txt')
    W_fc2 = W_fc2.reshape([HIDEN_SIZE, OUTPUT_SIZE])
    b_fc2 = np.loadtxt('./model/b_fc2.txt')
    
    # convolution layer 1
    x = np.zeros([IMG_SIZE, IMG_SIZE, 1])
    for i in range(IMG_SIZE):
        for j in range(IMG_SIZE):
            x[i, j, 0] = testImages[0, i*IMG_SIZE + j]/255.0
    temp = conv2d(x, W_conv1)
    for k in range(FILTER_SIZE):
        for h in range(IMG_SIZE):
            for w in range(IMG_SIZE):
                temp[h, w, k] += b_conv1[k]
    h_conv1 = relu3(temp)

    plt.figure(figsize=(5, 10))
    for k in range(FILTER_SIZE):
        plt.subplot(8, 4, k + 1)
        print("conv1 " + str(k))
        for i in range(IMG_SIZE):
            for j in range(IMG_SIZE):
                plt.plot(j, IMG_SIZE - i, '.', color=cm.jet(h_conv1[i, j, k]))
            plt.xlim(0, IMG_SIZE)
            plt.ylim(0, IMG_SIZE)
            plt.xticks(color='None')
            plt.yticks(color='None')
    plt.savefig('./model/conv1.png')
    
    h_pool1 = maxpool22(h_conv1)
    
    plt.figure(figsize=(3, 6))
    for k in range(FILTER_SIZE):
        plt.subplot(8, 4, k + 1)
        print("pool2 " + str(k))
        for i in range(int(IMG_SIZE/2)):
            for j in range(int(IMG_SIZE/2)):
                plt.plot(j, int(IMG_SIZE/2) - i, '.', color=cm.jet(h_pool1[i, j, k]))
            plt.xlim(0, IMG_SIZE/2)
            plt.ylim(0, IMG_SIZE/2)
            plt.xticks(color='None')
            plt.yticks(color='None')
    plt.savefig('./model/pool1.png')

    # convolution layer 2
    temp2 = conv2d(h_pool1, W_conv2)
    for k in range(FILTER_SIZE_2):
        for h in range(IMG_SIZE_2):
            for w in range(IMG_SIZE_2):
                temp2[h, w, k] += b_conv2[k]
    h_conv2 = relu3(temp2)

    plt.figure(figsize=(10, 10))
    for k in range(FILTER_SIZE_2):
        plt.subplot(8, 8, k + 1)
        print("conv2 " + str(k))
        for i in range(IMG_SIZE_2):
            for j in range(IMG_SIZE_2):
                plt.plot(j, IMG_SIZE_2 - i, '.', color=cm.jet(h_conv2[i, j, k]))
            plt.xlim(0, IMG_SIZE_2)
            plt.ylim(0, IMG_SIZE_2)
            plt.xticks(color='None')
            plt.yticks(color='None')
    plt.savefig('./model/conv2.png')

    h_pool2 = maxpool22(h_conv2)

    plt.figure(figsize=(5, 5))
    for k in range(FILTER_SIZE_2):
        plt.subplot(8, 8, k + 1)
        print("pool2 " + str(k))
        for i in range(int(IMG_SIZE_2/2)):
            for j in range(int(IMG_SIZE_2/2)):
                plt.plot(j, int(IMG_SIZE_2/2) - i, '.', color=cm.jet(h_pool2[i, j, k]))
            plt.xlim(0, IMG_SIZE_2/2)
            plt.ylim(0, IMG_SIZE_2/2)
            plt.xticks(color='None')
            plt.yticks(color='None')
    plt.savefig('./model/pool2.png')

    # Fully connecte layer
    h_pool2_flat = np.zeros([1, int(IMG_SIZE_2/2) * int(IMG_SIZE_2/2) * FILTER_SIZE_2])
    for i in range(int(IMG_SIZE_2/2)):
        for j in range(int(IMG_SIZE_2/2)):
            for k in range(FILTER_SIZE_2):
                h_pool2_flat[0, i*int(IMG_SIZE_2/2)*FILTER_SIZE_2 +  j*FILTER_SIZE_2 + k] = h_pool2[i, j, k]
    temp3 = ConnectFull(h_pool2_flat, W_fc1, b_fc1)
    h_fc1 = relu2(temp3)
    plt.figure(figsize=(5, 2))
    t = np.linspace(0, 1023, 1024)
    plt.plot(t, h_fc1.reshape([1024]))
    plt.savefig('./model/fc1.png')

    # output
    temp4 = ConnectFull(h_fc1, W_fc2, b_fc2)
    y_conv = softmax(temp4.reshape([10]))
    plt.figure(figsize=(5, 2))
    t = np.linspace(0, 9, 10)
    plt.plot(t, y_conv.reshape([10]))
    plt.savefig('./model/fc2.png')