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

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

詳細はこちら
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

深層学習

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

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

解決済

2回答

2446閲覧

pythonのone-hot型のRNN作成

kasappi

総合スコア3

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

深層学習

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

強化学習

強化学習とは、ある環境下のエージェントが現状を推測し行動を決定することで報酬を獲得するという見解から、その報酬を最大限に得る方策を学ぶ機械学習のことを指します。問題解決時に得る報酬が選択結果によって変化することで、より良い行動を選択しようと学習する点が特徴です。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2020/12/19 06:21

以下のようなcsvファイルをもちいてRNNの作成を行っています。データは1セットあたり99の時系列データと1つのラベルのセットで10セットあります。(学習用データとテスト用データで10個ずつ計20個)
イメージ説明

実現したいこと

99の時系列データの答えを1つのラベルとしてone-hot型で推定したいです。

実行したコード

# coding: utf-8 from __future__ import absolute_import from __future__ import division from __future__ import print_function import random import numpy as np import tensorflow as tf import csv from tensorflow.contrib import rnn # パラメーター N_CLASSES = 500 # クラス数 N_INPUTS = 1 # 1ステップに入力されるデータ数 N_STEPS = 20 # 学習ステップ数 LEN_SEQ = 99 # 系列長 N_NODES = 64 # ノード数 N_DATA = 10 # 各クラスの学習用データ数 N_TEST = 10 # テスト用データ数 BATCH_SIZE = 2 # バッチサイズ #データの準備 def get_data1(): with open("ファイル名") as fp: reader1 = csv.reader(fp) data1 = [ e for e in reader1 ] return data1 def get_data2(): with open("ファイル名") as fp: reader2 = csv.reader(fp) data2 = [ e for e in reader2 ] return data2 ・・・・・ def get__data20(): with open("ファイル名") as fp: reader20 = csv.reader(fp) data20 = [ e for e in reader20 ] return data20 def get_dataset1(): class_data1 = [get_data1(), get_data2()] ・・・・ class_data5 = [get_data9(), get_data10()] dataset1 = np.r_[class_data1, class_data2, class_data3, class_data4, class_data5] x1 = dataset1[:,:99] t1 = dataset1[:,99].reshape(-1) return x1, t1 def mist2_dataset(): class_data6 = [get_data11(), get_data12()] ・・・・ class_data10 = [get_data19(), get_data20()] dataset2 = np.r_[class_data6, class_data7, class_data8, class_data9, class_data10] x2 = dataset2[:,:99] t2 = dataset2[:,99].reshape(-1) return x2, t2 x_train, t_train = mist1_dataset() #学習用データセット x_test, t_test = mist2_dataset() #テスト用データセット # モデルの構築 x = tf.placeholder(tf.float32, [None, LEN_SEQ, N_INPUTS]) # 入力データ t = tf.placeholder(tf.int32, [None]) # 教師データ t_on_hot = tf.one_hot(t, depth=N_CLASSES, dtype=tf.float32) # 1-of-Kベクトル cell = rnn.BasicRNNCell(num_units=N_NODES, activation=tf.nn.tanh) # 中間層のセル # RNNに入力およびセル設定する outputs, states = tf.nn.dynamic_rnn(cell=cell, inputs=x, dtype=tf.float32, time_major=False) # [ミニバッチサイズ,系列長,出力数]→[系列長,ミニバッチサイズ,出力数] outputs = tf.transpose(outputs, perm=[1, 0, 2]) w = tf.Variable(tf.random_normal([N_NODES, N_CLASSES], stddev=0.01)) b = tf.Variable(tf.zeros([N_CLASSES])) logits = tf.matmul(outputs[-1], w) + b # 出力層 pred = tf.nn.softmax(logits) # ソフトマックス cross_entropy = tf.nn.softmax_cross_entropy_with_logits(labels=t_on_hot, logits=logits) loss = tf.reduce_mean(cross_entropy) # 誤差関数 train_step = tf.train.AdamOptimizer().minimize(loss) # 学習アルゴリズム correct_prediction = tf.equal(tf.argmax(pred,1), tf.argmax(t_on_hot,1)) accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # 精度 # 学習の実行 sess = tf.Session() sess.run(tf.global_variables_initializer()) i = 0 for _ in range(N_STEPS): cycle = int(N_DATA / BATCH_SIZE) begin = int(BATCH_SIZE * (i % cycle)) end = begin + BATCH_SIZE x_batch, t_batch = x_train[begin:end], t_train[begin:end] sess.run(train_step, feed_dict={x:x_batch, t:t_batch}) i += 1 if i % 2 == 0: loss_, acc_ = sess.run([loss, accuracy], feed_dict={x:x_batch,t:t_batch}) loss_test_, acc_test_ = sess.run([loss, accuracy], feed_dict={x:x_test,t:t_test}) print("[TRAIN] loss : %f, accuracy : %f" %(loss_, acc_)) print("[TEST loss : %f, accuracy : %f" %(loss_test_, acc_test_)) sess.close()

発生した問題

実行するとこのようになってしまいました。

[TRAIN] loss : 6.121445, accuracy : 0.000000 [TEST loss : 6.222018, accuracy : 0.000000 [TRAIN] loss : 6.161310, accuracy : 0.000000 [TEST loss : 6.225129, accuracy : 0.000000 [TRAIN] loss : 5.667954, accuracy : 0.500000 [TEST loss : 6.228346, accuracy : 0.000000 [TRAIN] loss : 5.720864, accuracy : 0.000000 [TEST loss : 6.232099, accuracy : 0.000000 [TRAIN] loss : 2.858102, accuracy : 0.000000 [TEST loss : 6.236712, accuracy : 0.000000 [TRAIN] loss : 5.295630, accuracy : 0.000000 [TEST loss : 6.242729, accuracy : 0.000000 [TRAIN] loss : 5.307451, accuracy : 0.000000 [TEST loss : 6.250314, accuracy : 0.000000 [TRAIN] loss : 4.823091, accuracy : 1.000000 [TEST loss : 6.259723, accuracy : 0.000000 [TRAIN] loss : 4.844704, accuracy : 0.000000 [TEST loss : 6.271129, accuracy : 0.000000 [TRAIN] loss : 2.439413, accuracy : 0.000000 [TEST loss : 6.284640, accuracy : 0.000000

おそらくone-hot型のところがうまくいっていないのかと思うのですが別で分類したい値を指定する必要がありますか?

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

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

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

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

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

jbpb0

2020/12/19 23:21

ラベルデータには、何が入っているのですか? 0〜499の整数ですか?
kasappi

2020/12/21 02:48

0〜500までの整数が20個入っています
jbpb0

2020/12/21 03:08

0から数えて500種類なので、499までです ラベルに500が有り得るなら、N_CLASSESは501です
kasappi

2020/12/21 03:37

501に変更しても同様の結果になりました
jbpb0

2020/12/21 05:15

> one-hot型のところがうまくいっていない 「# 学習の実行」のforループ内の sess.run(... の行のすぐ下に下記の3行を挿入したら、ループ内の各ステップで使われているt_batchとt_testがone hot表現で表示されますので、それと元のcsvファイルでのラベルを比較したら、意図した通りに変換されてるか確認できます print("i: " + str(i) + ", begin: " + str(begin) + ", end: " + str(end)) print("t_batch (1hot): " + str(sess.run(t_on_hot, feed_dict={t:t_batch}))) print("t_test (1hot): " + str(np.vsplit(sess.run(t_on_hot, feed_dict={t:t_test}), len(t_test)))) こちらで適当に作ったcsvファイルで確認したところでは、合ってるようですが なお、挿入する際は、sess.run(... の行にインデントを合わせてください
kasappi

2020/12/21 05:39

ありがとうございます。 TRAINのaccuracyも0.000000なのが気になるのですが、 ほかに考えられる原因はありますか?
jbpb0

2020/12/21 06:01 編集

同じところに下記を挿入したら、推論結果が取得できるはずなので、それとcsvファイルのラベルを比較して、lossやaccの計算が合ってるか検算してみるといいと思います #print("x_batch pred: " + str(sess.run(pred, feed_dict={x:x_batch}))) print("x_batch pred (max pos.): " + str(np.argmax(sess.run(pred, feed_dict={x:x_batch}), axis = 1))) #print("x_test pred: " + str(np.vsplit(sess.run(pred, feed_dict={x:x_test}), len(x_test)))) print("x_test pred (max pos.): " + str(np.argmax(sess.run(pred, feed_dict={x:x_test}), axis = 1))) 行頭の「#」を削除したら、推論の生値(ソフトマックスの結果)も表示されます
jbpb0

2020/12/21 06:25

https://qiita.com/exy81/items/8c9ab6ba8d4a03873d7c によると、「..._with_logits」は内部でソフトマックスを計算しているので、それに渡す値はソフトマックスを通さなくていいみたいです ただし、「pred = tf.nn.softmax(logits)」を「pred = logits」に変えても、結果は変わらないような気もします (確認してませんが)
jbpb0

2020/12/21 06:35

> TRAINのaccuracyも0.000000なのが気になる ラベルの0~500の数値は、単に違いを表しているのでしょうか? つまり、「ネコ」「自動車」「雲」みたいなものに数字を割り当てているだけなのでしょうか? それとも、数値として近いか遠いかに意味があるのでしょうか? たとえば、正解が400だとして、お書きになっているコードだと予想が100でも399でもどちらも400ではないからダメ、となり、399は400にかなり近いけど100は400から遠い、という違いが全く反映されませんけど、推測したいラベルはそういうものなのでしょうか? このコードだと、正解との差があまりなくておしいものがたくさんあっても、ピッタリ合ってるものが一つも無いとaccは0.0になります
kasappi

2020/12/21 06:39

上のコードを実行すると x_batch pred (max pos.): [469 170] x_test pred (max pos.): [469 469 469 469 469 469 469 170 170 170] x_batch pred (max pos.): [250 469] x_test pred (max pos.): [469 469 469 469 469 469 250 250 250 250] [TRAIN] loss : 6.105255, accuracy : 0.000000 [TEST loss : 6.228298, accuracy : 0.000000 x_batch pred (max pos.): [250 250] x_test pred (max pos.): [250 250 250 250 250 250 250 250 250 250] x_batch pred (max pos.): [250 250] x_test pred (max pos.): [250 250 250 250 250 250 250 250 250 250] [TRAIN] loss : 6.104594, accuracy : 0.000000 [TEST loss : 6.231257, accuracy : 0.000000  ...... と出てきましたが、何を表しているのでしょうか? ソフトマックスの件は変わりありませんでした。 ラベルは温度を表していて、近ければ近いほど良いです。(ピタリじゃなくても構いません。)
jbpb0

2020/12/21 08:43 編集

x_batch pred (max pos.): も x_test pred (max pos.): も、AIが予想したラベルです お書きになったコードの「# 学習の実行」のforループ内で、 x_batch, t_batch = x_train[begin:end], t_train[begin:end] により、x_trainから二つ(begin~end)だけを切り出してx_batchに格納してますよね たとえば、初回(i=0)はbegin=0, end=2ですから、x_train[0]とx_train[1]がx_batchとして使われます 次回(i=1)は、同様にしてx_train[2]とx_train[3]がx_batchとなります そのようにしてx_trainから二つだけ切り出して作られたx_batchからAIが予想したラベルが「x_batch pred (max pos.):」の右の二つの数値です 数値が二つなのは、x_batchに格納されたx_trainが毎回二つずつ(begin~end)だからです 一方、forループ内でx_testは切り出さずに毎回全部使ってますから、x_testの全部(10個)からAIが予想したラベルも10個あります それが「x_test pred (max pos.):」の右の10個の数値です 最初に提示した3行の最初の行(再掲します)も残していたら、i, begin, endも表示されて、x_trainは元csvのどのデータが予測に使われて結果が表示されているのかが分かりやすくなりますよ (x_testは毎回全部ですが) print("i: " + str(i) + ", begin: " + str(begin) + ", end: " + str(end))
jbpb0

2020/12/21 07:54 編集

> ラベルは温度を表していて、近ければ近いほど良いです。(ピタリじゃなくても構いません。) それでしたら、分類問題じゃなくて、回帰問題にした方がいいと思います 正解400に対して、予測100はダメダメだけど、予測399はおしい、ってAIに教えてあげないと、AIはガンバレない 今のコードでは、100でも399でもダメって言ってるだけ
kasappi

2020/12/21 15:56

ありがとうございます。 回帰問題でもコードのベースの形は変えずにできますか?? (ラベルを推定するone-hot型でできますか?)
jbpb0

2020/12/22 09:02

> 回帰問題でもコードのベースの形は変えずにできますか?? > (ラベルを推定するone-hot型でできますか?) 普通は、回帰ではone hot表現にはしません 正解の数値と、AIが予想した数値の、差の2乗の平均(MSE)をlossに設定すれば最適化できるので、わざわざone hot表現にする必要がないからです どうしてもone hot表現でやりたいなら、correct_predictionを計算しているところでやっているように、正解と予測値のone hot表現のそれぞれのargmaxを計算すれば、それはone hot表現にする前の値の生値に近いから、その差の2乗の平均をlossにすれば、普通の回帰と同じようなことになるはずなので、最適化できそうな気もします (けど、そんなことやったことないので分からない)
jbpb0

2020/12/22 10:56

lossを下記のようにargmaxの差の2乗の平均に書き直してみましたが、勾配が計算できないと怒られました mse = tf.square(tf.subtract(tf.cast(tf.argmax(pred,1), tf.float32), tf.cast(tf.argmax(t_on_hot,1), tf.float32))) loss = tf.reduce_mean(mse) 素直にAIの予測値を数値としてそのまま扱わないと、回帰はできないみたいです
kasappi

2020/12/23 01:04

ありがとうございます。自分で頑張ってみます。
guest

回答2

0

回帰問題に書き直すと、こんな感じ
csvファイルをたくさん用意するのがめんどくさかったので、そこは手を抜いてます

python

1# coding: utf-8 2from __future__ import absolute_import 3from __future__ import division 4from __future__ import print_function 5 6import random 7import numpy as np 8import tensorflow as tf 9import csv 10from tensorflow.contrib import rnn 11 12# パラメーター 13N_CLASSES = 1 # クラス数 14N_INPUTS = 1 # 1ステップに入力されるデータ数 15N_STEPS = 200 # 学習ステップ数 16LEN_SEQ = 99 # 系列長 17 18N_NODES = 64 # ノード数 19N_DATA = 10 # 各クラスの学習用データ数 20N_TEST = 10 # テスト用データ数 21BATCH_SIZE = 2 # バッチサイズ 22 23#データの準備 24def get_data1(): 25 with open("test1.csv") as fp: 26 reader1 = csv.reader(fp) 27 data1 = [ e for e in reader1 ] 28 return data1 29 30def get_data2(): 31 with open("test2.csv") as fp: 32 reader2 = csv.reader(fp) 33 data2 = [ e for e in reader2 ] 34 return data2 35 36def mist1_dataset(): 37 class_data1 = [get_data1(), get_data2()] 38 class_data2 = [get_data1(), get_data2()] 39 class_data3 = [get_data1(), get_data2()] 40 class_data4 = [get_data1(), get_data2()] 41 class_data5 = [get_data1(), get_data2()] 42 dataset1 = np.r_[class_data1, class_data2, class_data3, class_data4, class_data5] 43 x1 = dataset1[:,:99] 44 t1 = dataset1[:,99].reshape(-1) 45 return x1, t1 46 47def mist2_dataset(): 48 class_data6 = [get_data1(), get_data2()] 49 class_data7 = [get_data1(), get_data2()] 50 class_data8 = [get_data1(), get_data2()] 51 class_data9 = [get_data1(), get_data2()] 52 class_data10 = [get_data1(), get_data2()] 53 dataset2 = np.r_[class_data6, class_data7, class_data8, class_data9, class_data10] 54 x2 = dataset2[:,:99] 55 t2 = dataset2[:,99].reshape(-1) 56 return x2, t2 57 58x_train, t_train = mist1_dataset() #学習用データセット 59x_test, t_test = mist2_dataset() #テスト用データセット 60 61# モデルの構築 62x = tf.placeholder(tf.float32, [None, LEN_SEQ, N_INPUTS]) # 入力データ 63t = tf.placeholder(tf.float32, [None]) # 教師データ 64cell = rnn.BasicRNNCell(num_units=N_NODES, activation=tf.nn.tanh) # 中間層のセル 65# RNNに入力およびセル設定する 66outputs, states = tf.nn.dynamic_rnn(cell=cell, inputs=x, dtype=tf.float32, time_major=False) 67# [ミニバッチサイズ,系列長,出力数]→[系列長,ミニバッチサイズ,出力数] 68outputs = tf.transpose(outputs, perm=[1, 0, 2]) 69 70w = tf.Variable(tf.random_normal([N_NODES, N_CLASSES], stddev=0.01)) 71b = tf.Variable(tf.zeros([N_CLASSES])) 72pred = tf.matmul(outputs[-1], w) + b # 出力層 73 74se = tf.square(tf.subtract(pred, t)) 75loss = tf.reduce_mean(se) # 誤差関数 76train_step = tf.train.AdamOptimizer().minimize(loss) # 学習アルゴリズム 77 78# 学習の実行 79sess = tf.Session() 80sess.run(tf.global_variables_initializer()) 81i = 0 82for _ in range(N_STEPS): 83 cycle = int(N_DATA / BATCH_SIZE) 84 begin = int(BATCH_SIZE * (i % cycle)) 85 end = begin + BATCH_SIZE 86 x_batch, t_batch = x_train[begin:end], t_train[begin:end] 87 sess.run(train_step, feed_dict={x:x_batch, t:t_batch}) 88 i += 1 89 if i % 2 == 0: 90 loss_ = sess.run(loss, feed_dict={x:x_batch,t:t_batch}) 91 loss_test_ = sess.run(loss, feed_dict={x:x_test,t:t_test}) 92 print("step: %d, TRAIN loss: %e, TEST loss: %e" %(i, loss_, loss_test_)) 93 #print("i: " + str(i) + ", begin: " + str(begin) + ", end: " + str(end)) 94 #print("t_batch: " + str(sess.run(t, feed_dict={t:t_batch}))) 95 #print("x_batch pred: " + str(np.ndarray.flatten(sess.run(pred, feed_dict={x:x_batch})))) 96 #print("t_test: " + str(sess.run(t, feed_dict={t:t_test}))) 97 #print("x_test pred: " + str(np.ndarray.flatten(sess.run(pred, feed_dict={x:x_test})))) 98 #print("") 99 100sess.close()

投稿2020/12/23 11:51

編集2020/12/23 11:54
jbpb0

総合スコア7653

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

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

kasappi

2021/01/18 04:46

ありがとうございます。 現在、RNNを通常のNNに書き換えて回帰型で作成しています。 どの部分を書き換えればよいでしょうか?
guest

0

自己解決

分類問題なので数値がぴったり合ってないと結果としてあらわれないことが分かった

投稿2020/12/23 01:05

kasappi

総合スコア3

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

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

jbpb0

2020/12/23 12:12

データ数を増やすか、クラス数を減らせば、分類問題でもうまくいくと思います 500クラス分類に対して10~20のデータ数では、少なすぎます データ数を増やせないなら、クラスを3~5くらいに減らすとか 気温なら、10℃間隔とか、寒い・ちょうどいい・暑い の3分類とか たとえばmnistは、数字10種類分類でテストデータ10000枚ですから、約1000枚の0の画像の内の約100枚はデタラメに分類しても正解するわけです AIはその100枚が正解する状態からスタートして、いろいろやって正解枚数が増える方向に進むわけです 一方、500クラス分類でデータが10~20だと、デタラメに分類したら偶然正解する確率はとても低いです だから、AIは改善の手がかりが掴めず、いろいろ工夫してもかすりもせず、ジタバタしたまま終わるわけです すごくたくさんの回数試行を行えば、そのうちに偶然一致する場合が出てきて、さらに試行数を増やせば、そういう組み合わせがだんだん増えるかもしれませんが、効率が悪いです ・データ数を増やす(分類クラス数よりも多く) ・分類クラス数を減らす(データ数よりも少なく) ・回帰問題に変える のいずれかを行うことをお勧めします
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問