🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2631閲覧

kerasを使ったCNNの回帰学習を行なっているのですが、予測値が一定になります助けてください

Taiira

総合スコア1

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/09 07:13

編集2021/02/09 11:55

前提・実現したいこと

人の約2万の代謝物をt-sne次元圧縮法を使って画像化された143人分の画像データを学習データに、それらの人の年齢を教師データにして、CNNを用いた回帰学習を行いたいです。実行するとエラーを出さずに、最後まで動きます。(実行時間10分程度)。しかし、model.predictを行うと一定の値した出力されず、学習ができていません。
環境 macOS big sur ver 11.2 、python3.6 、jupyter notebook、 tensorflow

質問事項
・model.predict(X_test)を実行し、テストデータの年齢を予測すると全部同じぐらいの数字として予測されます。(out_put: array([[50.41556 ], [50.415688],[50.41586 ],[50.415657],[50.416435],[50.416126],[50.415924],[50.415714],[50.415657],[50.415928],[50.41616 ],[50.415886],[50.416042],[50.416138],[50.415443]], dtype=float32) )これは、データが足りないということなのでしょうか、それともコーディングが間違っているのでしょうか?テストデータは画像の青色の部分から抽出されているので、教師データは本来、一定の値ではありません
・tensorflowで学習のログを確認した時、損失関数の分布が、参考書で見るようなシグモイド曲線になりません。どうすればよいでしょうか?

発生している問題・エラーメッセージ

該当のソースコード

python

1ソースコード 2import glob 3import re 4import os 5import cv2 6import numpy as np 7import matplotlib.pyplot as plt 8from PIL import Image 9from sklearn.model_selection import train_test_split 10import tensorflow as tf 11from tensorflow.keras import datasets, layers, models 12from tensorflow.keras.layers import Dropout, Flatten, Dense 13 14img_dir ='PATH' #ディレクトリのPATH 15types = [ 'sample_data*.png'] #ディレクトリの中の画像ファイルを格納 16paths = [] 17for t in types: 18 paths.extend(glob.glob(os.path.join(img_dir, t)))#pathsに画像ファイルを格納 19 20X = [] 21Y = [] 22for f in paths: 23 img = cv2.imread(f) 24 img = np.asarray(img) 25 X.append(img)#Xに画像データを格納 26 27 f =re.sub(' PATH ','',f) #画像ファイルの名前から教師ラベルを抽出 28 f =re.sub('[0-9]+','',f,1) 29 f =re.search(r'\d+', f) 30 f =f.group() 31 Y.append(f)#Yに教師ラベルを格納 32 33Y = np.array(Y) 34Y = Y.astype(float) 35X = np.array(X) 36print(X.shape,Y.shape)#Xの画像データを行列に変換 37X = X / 255.0 38Y = Y / 100#損失関数を小さくするために表記 39 40X_train, X_test, y_train, y_test = train_test_split(X,Y,random_state = 0,test_size = 0.1)#XとYをtrain_dataとtest_dataに分ける 41print(X_train.shape, y_train.shape, X_test.shape, y_test.shape) #データの確認 42 43model = models.Sequential()#CNNモデル構築、input画像は、500×500 ピクセルRGBの画像データ 44model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(500, 500, 3))) 45model.add(layers.MaxPooling2D((2, 2))) 46model.add(layers.Conv2D(64, (3, 3), activation='relu')) 47model.add(layers.MaxPooling2D((2, 2))) 48model.add(layers.Conv2D(64, (3, 3), activation='relu')) 49model.add(layers.MaxPooling2D((2, 2))) 50model.add(Flatten()) 51model.add(layers.Dense(64, activation='relu')) 52model.add(Dense(1)) 53model.summary() 54 55model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=0.0001),#モデルのコンパイルと学習、確立的勾配降下法(SDG)X: 画像のデータ、Y :目的関数(教師ラベル) 56 loss='mse',#損失関数 57 metrics=['mae']) 58 59tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir="PATH_flog/", 60 histogram_freq=1)#TensorBoardで学習のログを残す 61 62model.fit(X_train, y_train, batch_size=16, epochs=8,verbose=1,callbacks=[tensorboard_callback]) 63test_loss,test_acc = model.evaluate(X_test, y_test, verbose=1) 64 65print(test_loss) 66 67model.predict(X_test)

試したこと

rensorflowで学習を可視化
損失関数を小さくするために、Y を0〜1での範囲で示すように変更(658→0.071)

補足情報(FW/ツールのバージョンなど)

損失関数の分布

学習データの年齢の分布
*青色がtestデータ、赤色がtrainデータ
学習マップ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/02/09 09:04

pythonのコードの一番最初の行のすぐ上に ```python だけの行を追加してください また、pythonのコードの一番最後の行のすぐ下に ``` だけの行を追加してください 現状、コードがとても読み辛いです 質問にコードを載せる際に上記をやってくれたら、他人がコードを読みやすくなり、回答されやすくなります
jbpb0

2021/02/09 09:49 編集

> ・損失関数(loss)が658になります。これは、参考書では0.9などになっていて loss='mse' なので、平均の誤差が√658≒26くらいなのでしょう 誤差が大きすぎるかもしれないので、Yを100.0で割って、Yの範囲を0.0〜1.0にしてみたらいかがでしょうか
Taiira

2021/02/09 11:58

ありがとうございます。Yを0~1の範囲の数字に変更したことによって損失関数が0.071になりました。 しかし、model.predictで予測値を出力すると、一定値で予測されます。これは、訓練データが少ないことに起因する現象なのでしょうか。
jbpb0

2021/02/09 12:55

model.fitの後のmodel.evaluateやmodel.predictをX_train, y_trainで行ったら、うまくいきますか? その結果は良いなら、過学習を抑える対策を入れるとか、データを増やすとか、が必要ですね
jbpb0

2021/02/09 13:07

もし、model.evaluateやmodel.predictをX_train, y_trainで行ってもうまくいかないなら、学習ができてません その場合は、データの問題かコードの問題か切り分けるため、同じコードで、もっと簡単に学習・予測できることをやってみたらいかがでしょうか たとえば、画像の平均の明るさをYにしたら、学習も予測も簡単にうまくいくはず それならば同じコードでうまくいくなら、現在入力に使ってる画像から年齢を予測するのがとても困難なのかもしれません (画像と年齢の相関があまり無い)
Taiira

2021/02/10 02:13

model.predictをX_trainを行なったところ、X_testと同じように、予測値が一定という結果になりました。これは、@jbpb0さんの言うところの学習ができていないことを示しているのだと思います。 コードの問題を検証するために、簡単な画像データを作って動かしてみようと思います。
jbpb0

2021/02/10 03:58 編集

同じコードで簡単な教師データならうまくいったとして、その画像(t-sne次元圧縮法)の作り方に実績(cnnで分類ができた)があって、画像を作るツールの使い方も間違ってないとすれば、最終精度が十分かは置いといて、全く学習できないはずはないですよね ・batch_sizeを変えてみる ・learning_rateを変えてみる ・epochsを増やしてみる とかすると、良くなる条件があるのかも あくまでも、コードに問題が無いことが確認できた上での話ですが
toast-uz

2021/02/10 10:12

・Yのサイズを変えているので、medel.predictの出力もそれに引っ張られます。逆変換しましょう。 ・TensorBoardは使ったこと無いですが、3つのグラフそれぞれに複数本の線があるのは、何に対応しているのでしょうか(そもそもYのサイズ変更前のグラフな気がします)?epoch_lossの右下がりの線が本命なのでれば、epochごとに急速にlossが改善している最中であり、epoch数が圧倒的に足りていません。 ・model.evaluateを使うのでなく、model.fitで、validation_data=(X_test, y_test)を入れましょう。epochごとにテストデータで検証できるので、過学習が判別できます。 ・optimizersは、特別な理由がない限りAdamにしましょう。learning_rateはデフォルト0.001から変えない方が良いです。デフォルトより増やす方向の調整が経験上多いですので、減らしているのは悪手。
toast-uz

2021/02/10 10:31

あと、実績あるパッケージを使われているとのことですが、CNNのレイヤー構造も実績あるものなのでしょうか?500×500の巨大画像がinputなので、3×3カーネルでの畳込み・3層のみ、というのは、感覚的に小さい・少ない印象があります。
Taiira

2021/02/10 12:15

ありがとうございます。 ・TensorBoardに関しては、学習のログをリセットされておらず、ログが重複していることが原因と考えられます。ログをリセットした上でやり直してみます。 ・optimizerは、無知ゆえに、とりあえずでSDGで行なっていたため、Adamに変えようと思います。 ・また、畳みこみのフィルターサイズに関しては、500×500のような画像で行なっている例が、なかった ため、3×3で試しています。層に関しても、基本的に2層以上必要ということしか知らなかったため三層で行なっています。これらのサイズはどれくらいまで大きくしていいのでしょうか?
toast-uz

2021/02/10 12:49

畳み込みについては特にこれという指針は無く、似たような成功モデルをマネるのがよいです。 なお、サンプルデータ数が少ないかもですね。回答側で記述いただいたリンクを見ると、サンプル数6,216枚でした。
Taiira

2021/02/12 04:51

今後は ・サンプルの数を増やす ・畳み込みのパラメーター(カーネルサイズ)と学習の層の数を増やす という方向で進めていこうと思います。(以下補足…) プログラムの健全性を評価するために、テストデータでの検証を行いました。テストデータ(教師関数として1~100の数字を持ち、画像データには500×500×3で1画像の1ピクセル数字は全て均一、で教師関数が1増えるごとに画像のピクセルの数字が1増える)。このデータ100枚で学習を行なったところ、model.predictの結果は、20程度の幅をもったデータ(40~60)が出力されました。これは均一の値を出力していないことから、学習を行えている、プログラムは妥当であると考えています。加えて、データを1000に増やしたところ、model.predictの結果は、改善されました。データを増やすアプローチの正当性が示唆されました。
guest

回答1

0

ベストアンサー

人の約2万の代謝物をt-sne次元圧縮法を使って画像化された143人分の画像データを学習データに

率直に思ったこととしては、t-sneの画像をCNNに入れて……というのはそもそも無理筋ではないですかね? 

t-sneの変換自体、可視化はできてもさほど厳密なものではありませんし、個体ごとに別々にt-sneをかけているとすればそれぞれでまったく異なる変換が施されます。それでもなんらかの構造が現れてくれると仮定したとしても、ランダムに回転するので画像認識には困難が伴いそうです。

投稿2021/02/09 18:54

hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Taiira

2021/02/10 01:38

回答ありがとうございます。 t-sheの処理としては、全個体データに一括して同様の処理をしています。cnnで学習することを前提に次元圧縮を行うパッケージを開発された方がいまして、私はそのパッケージを使わせてもらっています。その方は本件と同じように個体ごとに画像化を行なっており、その後、分類学習を行なっていました。 そういった背景から、パッケージを使用し個体ごとにデータ画像化して、回帰学習を行いたいのですが、難しいのでしょうか
hayataka2049

2021/02/10 09:04 編集

難しそうだ、というフィーリングを回答しただけなので、理論的・実証的に「いける」ということであれば、それはそれで構いません。他のところに原因があるのだろう、ということになります。 そのパッケージの情報を教えていただけますか?
hayataka2049

2021/02/11 12:28

見た感じ面白いといえば面白いのですが、そこまで良いかこれ……変数クラスタリングして画像化するなら、昔からあるSOMとかと変わらない気がした。 t-sneはうまくいっているとすれば、データセットが1桁足りないとか、シンプルにモデルの構造が悪いとか、そんなところでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問