iT邦幫忙

2022 iThome 鐵人賽

DAY 13
0

廢廢吸取了昨天的教訓,改換方法。

資料處理

今天將資料分成的x.csv(牌局資料)與y.csv(label),先寫入train.csv的header(label、1x1x1、1x1x2),如下:
https://ithelp.ithome.com.tw/upload/images/20220925/20145527m4lbOXcWRx.png
再將x.csv的15個column轉成二維並插入新的陣列變成深度為15且17x17大小的三維矩陣,轉換好後攤平成一維陣列並且在前面插入label後寫入train.csv。

#整合前面零散的code
import random
import numpy as np
import numpy as reshape
import csv
"""把data & label連在一起並且轉成CNN圖片格式寫入train.csv"""
x=[]
y=[]
size = np.array([[0]*17]*17) #二維資料
rrow=[]
roww=[]
all = []

print("reading file...")
with open('test_x.csv', newline='') as csvfile:
    # 讀取 CSV 檔內容,將每一列轉成一個 dictionary
    #rows = csv.DictReader(csvfile) #csv.DictReader可以資料查找 d = {key1: value1, key2: value2}
    rows = csv.reader(csvfile)
    data_list = list(rows)

with open('test_y.csv', newline='') as file:
    # 讀取 CSV 檔內容,將每一列轉成一個 dictionary
    #rows = csv.DictReader(csvfile) #csv.DictReader可以資料查找 d = {key1: value1, key2: value2}
    rows = csv.reader(file)
    data_list_y = list(rows)

print("list insert to array...")
for a in range(len(data_list)):
    x.append(data_list[a])
x=np.array(x)

for a in range(len(data_list_y)):
    y.append(data_list_y[a])


print("create train.csv...")
file = open('train.csv',mode='w', newline='')
writer = csv.writer(file)
headers = ['label']

for a in range(15):
    for b in range(17):
        for c in range(17):
            headers.append(str(a+1)+'x'+str(b+1)+'x'+str(c+1))

writer.writerow(headers)

print("start convert to 3D-array...")
for b in range(len(x)):
    for c in range(15):
        if c == 9 or c == 10:
            x[b,c]=float(x[b,c])
        else:
            x[b,c]=int(x[b,c])

for i in range(len(x)):
    for j in range(15):
        if j >= 1 and j <=7 : #放撲克編碼
            if int(x[i,j]) == -1:
                size[random.randrange(0,16,1),random.randrange(0,16,1)] = 0
            else:
                suit=int(x[i,j]) % 4
                rank=int(x[i,j]) // 4
                size[suit,rank] = 1
        else:
            if j==9:#小數籌碼
                size[6, 0] = float(x[i,j])
            elif j==10: 
                size[7, 1] = float(x[i,j])
            else:
                if int(x[i,j]) == -1:
                    size[random.randrange(0,16,1),random.randrange(0,16,1)] = 0
                else:
                    if j==0:
                        size[4, int(x[i,j])] = int(x[i,j])
                    elif j==8:
                        size[5, int(x[i,j])] = int(x[i,j])
                    else:
                        size[j, int(x[i,j])] = int(x[i,j])

        for k in range(17):
            all.append(size[k,])
            rrow.extend(size[k,])

        size = np.array([[0]*17]*17) #二維資料
    y[i].extend(rrow)
    writer.writerow(y[i])
    rrow=[]

file.close()

all = np.array(all)
all = all.reshape(len(x),15,17,17)
print('维数:',all.shape)

CNN模型

開始執行CNN並且儲存模型,這邊為了能快點執行只用了10筆資料進行測試,程式碼參考了這兩個網站:
以100張圖理解 Neural Network -- 觀念與實踐系列 第 7 篇
使用自己的csv文件數據進行神經網絡學習時的數據處理

import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation, Flatten
# 用來後續將 label 標籤轉為 one-hot-encoding
from keras.utils import np_utils
from matplotlib import pyplot as plt
from sklearn.model_selection import train_test_split
import pandas as pd

dataset=pd.read_csv('train.csv')#文件读取
dataset = dataset.values#去掉標頭

#train.csv第一列为数字类别标签,后面所有列均为像素值,故一共785列(784+1)
data = np.array(dataset[:,:-1]) #从第二列开始读取为训练数据
label = np.array(dataset[:,0:1]) #读取第一列为数字类别标签
data = np.reshape(data, (-1,17,17,15)) #更改为网络输入类型,即原始图像shape(28*28*1)
	
train_data,test_data,train_label,test_label = train_test_split(data,label,test_size=0.2)
#按照8:2划分训练集和验证集


# 將 training 的 label 進行 one-hot encoding,例如數字 7 經過 One-hot encoding 轉換後是 array([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.], dtype=float32),即第7個值為 1
train_label_onehot = np_utils.to_categorical(train_label)
test_label_onehot = np_utils.to_categorical(test_label)

# 將 training 的 input 資料轉為 28*28 的 2維陣列
# training 與 testing 資料數量分別是 60000 與 10000 筆
# train_data_2D 是 [60000, 28*28] 的 2維陣列
train_data_2D = train_data.reshape(8, 15*17*17).astype('float32')
test_data_2D = test_data.reshape(2, 15*17*17).astype('float32')

train_data_norm = train_data_2D/255
test_data_norm = test_data_2D/255


# 建立簡單的線性執行的模型
model = Sequential()
# Add Input layer, 隱藏層(hidden layer) 有 256個輸出變數
model.add(Dense(units=256, input_dim=4335, kernel_initializer='normal', activation='relu'))
# Add output layer
model.add(Dense(units=5, kernel_initializer='normal', activation='softmax'))

# 編譯: 選擇損失函數、優化方法及成效衡量方式
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])


# 進行 model 訓練, 訓練過程會存在 train_history 變數中
# 將 60000 張 training set 的圖片,用 80% (48000張) 訓練模型,用 20% (12000張) 驗證結果
# epochs 10 次,就是訓練做了 10 次
# batch_size 是 number of samples per gradient update,每一次進行 gradient descent 使用幾個 samples
# verbose 是 train_history 的 log 顯示模式,2 表示每一輪訓練,列印一行 log
train_history = model.fit(x=train_data_norm, y=train_label_onehot, validation_split=0.2, epochs=10, batch_size=64, verbose=2)

# 用 10000 筆測試資料,評估訓練後 model 的成果(分數)
scores = model.evaluate(test_data_norm, test_label_onehot)
print()
print("Accuracy of testing data = {:2.1f}%".format(scores[1]*100.0))

# 預測(prediction)
print(test_data_norm)
X = test_data_norm[0:10,:]
print("X: ", X)
predictions = model.predict(X)
# get prediction result
predict = np.argmax(predictions,1)
print("predict: ",predict)

# 模型訓練結果 結構存檔
from keras.models import model_from_json
json_string = model.to_json()
with open("model.config", "w") as text_file:
    text_file.write(json_string)

# 模型訓練結果 權重存檔
model.save_weights("model.weight")

# 顯示 第一筆訓練資料的圖形,確認是否正確
#plt.imshow(train_data[0])
#plt.show()
#plt.imsave('1.png', train_data[0])

plt.clf()

plt.plot(train_history.history['loss'])
plt.plot(train_history.history['val_loss'])
plt.title('Train History')
plt.ylabel('loss')
plt.xlabel('Epoch')
plt.legend(['loss', 'val_loss'], loc='upper left')
#plt.show()
plt.savefig('loss.png')

接下來廢廢預計輸入測試用資料來進行預測,以上記錄到此明天見吧各位!


上一篇
DAY 12 資料集分成train & valid
下一篇
DAY 14 資料轉換等待中......
系列文
關於因耍廢太久而必須挑戰5個月上研究所的廢廢38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言