Conv1Vで画像分類を試していますが、lossが0のまま変化しません。
解決したいこと
2種類の画像データを読み取って、Cov1Dで分類するコードを書きましたが、lossが0のまま変わらないため、正しく判定することができません。
発生している問題・エラー
accuracyは学習とともに値が変わっているのに対し、lossは0のまま変化がありません。
例)
Epoch 50/50
13/13 [==============================] - 5s 369ms/step - loss: 0.0000e+00 - accuracy: 0.7087 - val_loss: 0.0000e+00 - val_accuracy: 0.0000e+00
該当するソースコード
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 10 19:46:13 2022
@author:
"""
from tensorflow.keras.layers import Input,Dense
from tensorflow.keras.models import Model
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from PIL import Image
import os
import pprint
from sklearn.metrics import confusion_matrix
from sklearn import metrics
from matplotlib import cm
import tensorflow as tf
from tensorflow import keras
from scipy.special import boxcox, inv_boxcox
from scipy import stats
img_width, img_height =64, 64
# 学習用のデータを読み取る.
image_list_train = []
label_list_train = []
# ./data/train 以下のcosmosディレクトリ以下の画像を読み込む。
for dir in os.listdir("data/train"):
if dir == ".DS_Store":
continue
dir1 = "data/train/" + dir
label = 0
if dir == "cosmos": # cosmosはラベル0
label = 0
elif dir == "sakura": # sakuraはラベル1
label = 1
for file in os.listdir(dir1):
if file != ".DS_Store":
# 配列label_listに正解ラベルを追加(cosmos:0 sakura:1)
label_list_train.append(label)
filepath = dir1 + "/" + file
# 画像をn×n(n=50)pixelに変換し、1要素が[R,G,B]3要素を含む配列のnxnの2次元配列として読み込む。
# [R,G,B]はそれぞれが0-255の配列。
image = Image.open(filepath).resize((img_width, img_height))
image = image.convert("RGB")
image = np.array(image)
# 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。
# さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。
image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0]
# 出来上がった配列をimage_listに追加。
image_list_train.append(image / 255.)
# kerasに渡すためにnumpy配列に変換。
x_input = np.array(image_list_train)
print("x_input",x_input.shape)
# ラベルの配列を1と0からなるラベル配列に変更
#dataset_ytr=np.array(label_list_train)
y_input=np.array(label_list_train)
print("y_input",y_input.shape)
# 判定用のデータを読み取る.
image_list_test= []
label_list_test = []
# ./data/test 以下のcosmos,sakuraディレクトリ以下の画像を読み込む。
for dir in os.listdir("data/test"):
if dir == ".DS_Store":
continue
dir1 = "data/test/" + dir
label = 0
if dir == "cosmos": # cosmosはラベル0
label = 0
elif dir == "sakura": # sakuraはラベル1
label = 1
for file in os.listdir(dir1):
if file != ".DS_Store":
# 配列label_listに正解ラベルを追加(cosmos:0, sakura:1)
label_list_test.append(label)
filepath = dir1 + "/" + file
# 画像をn×n(n=50)pixelに変換し、1要素が[R,G,B]3要素を含む配列のnxnの2次元配列として読み込む。
# [R,G,B]はそれぞれが0-255の配列。
image = Image.open(filepath).resize((img_width, img_height))
image = image.convert("RGB")
image = np.array(image)
# 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。
# さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。
image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0]
# 出来上がった配列をimage_listに追加。
image_list_test.append(image / 255.)
# kerasに渡すためにnumpy配列に変換。
x_test = np.array(image_list_test)
#x_test = np.transpose(0, 1, 2)
print("x_test", x_test.shape)
# ラベルの配列を1と0からなるラベル配列に変更
y_test= np.array(label_list_test)
print("y_test", y_test.shape)
from keras.layers.convolutional import Conv1D, MaxPooling1D
from keras.models import Sequential
from tensorflow.keras import layers
from keras.layers.core import Dense, Dropout, Activation, Flatten
from keras import optimizers
model = Sequential()
model.add(Conv1D(8, kernel_size=3, input_shape=(12288,1)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(800))
model.add(Activation('relu'))
model.add(Dense(400))
model.add(Activation('relu'))
model.add(Dense(200))
model.add(Activation('relu'))
model.add(Dense(100))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('sigmoid'))
model.summary()
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
history = model.fit(x_input, y_input, batch_size=8, epochs=50,validation_split=0.1, verbose = 1)
y_pred = model.predict(x_test)
print("y_pred",y_pred.shape)
np.savetxt('y_pred.csv',y_pred)
from sklearn.metrics import accuracy_score
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
Accuracy = accuracy_score(y_test, y_pred)*100
Precision = precision_score(y_test, y_pred)*100
Recall = recall_score(y_test, y_pred)*100
F1 = f1_score(y_test, y_pred)*100
report_list = ['Accuracy', 'Precision', 'Recall', 'F1']
report_value = [Accuracy, Precision, Recall, F1]
# Confution_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)
print("Accuracy", Accuracy)
print("Precision", Precision)
print("Recall", Recall)
print("F1", F1)
# ROC曲線
cnt=0
point=[0,0]
roc=[]
roc.append([0,0])
rank=list(reversed(np.argsort(y_test)))
error=np.sum((y_test.astype("int")==1))
for ridx in rank:
if y_test[ridx]==1:
point[1]=point[1]+1
cnt=cnt+1
else:
point[0]=point[0]+1
roc.append([point[0],point[1]])
if cnt==error:
roc.append([y_test.shape[0],point[1]])
break
roc=np.array(roc)
np.savetxt("roc.txt",roc)
plt.plot(roc[:,0]/y_test.shape,roc[:,1]/error)
plt.plot([0,1],color='black',linestyle='dashed')
plt.savefig("ROC_curve.png")
plt.show()
# Plot training & validation loss values
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.savefig("loss-epoch.png")
plt.show()
例)
def greet
puts Hello World
end
自分で試したこと
optimizerをadamからsgdにしたところ、lossがNanになりました。