ITの隊長のブログ

ITの隊長のブログです。Rubyを使って仕事しています。最近も色々やっているお(^ω^ = ^ω^)

Tensorflow2系の基本的なデータの読み込み方

スポンサードリンク

Tensorflow2系触っていますが、情報が少なくて死にそうです。

しかし、ドキュメントは結構しっかりしているかなと思っています。ドキュメント読むべし。

参考URL

Importing Data  |  TensorFlow Core  |  TensorFlow

環境

  • colaboratory
  • !pip install tensorflow-gpu==2.0.0-alpha0
  • Python3.6.7

データの読み込み

import numpy as np
import tensorflow as tf
from sklearn.model_selection import train_test_split

# 検証用データの用意
# Tensorflowから関係ない形式でとってきたと想定でやる
val_x_data = np.random.uniform(0, 1, (60000, 32, 32))
val_y_data = np.random.randint(0, 5, (60000))
val_x_data.shape, val_y_data.shape
# ((60000, 32, 32), (60000,))

TensorflowはKerasも取り込みましたし、自身でのデータセットのロードも関数が用意されていますが、フォーマットがわからずイライラする方もいるんじゃないかと。また、今データ分析やっている人は、生データがあって、そこからTensorflowの世界にもってってディープラーニングしたい人が多いんじゃないかなーと思うので、それを想定して試してみました。

# モデルを構築するならtrain, test分割
X_train, X_test, y_train, y_test = train_test_split(val_x_data, val_y_data, test_size=0.3)

Tensorflowの世界に持ってくる

Tensorflowの世界にもっていくとPythonより速度が速く処理できるそうです。

train_data = tf.data.Dataset.from_tensor_slices((X_train, y_train))

読み込んで作成したデータは、TensorSliceDataset になる

train_data
# <TensorSliceDataset shapes: ((32, 32), ()), types: (tf.float64, tf.int64)>

TensorSliceDataset のデータで前処理したい

データを何かで処理したい場合は、mapを使う. pythonの世界にもってくると処理が遅いのでオススメしないらしいが一応できます.

# 今回、X_train, y_trainでデータを作ったので引数は2つです
def hogehoge(x, y):
    x = tf.reshape(x, [-1,])
    return x, y # 戻り値は用意する必要があります


train_data_map = train_data.map(hogehoge)

確認すると処理されたデータになっています.

# 変換されました.
train_data_map.take(1)
# <TakeDataset shapes: ((1024,), ()), types: (tf.float64, tf.int64)>

データを回しながら取得する.

.take(n) で指定した n 個分、取得することができます。

# データを10個確認する
for x, y in train_data_map.take(10):
    print(x.shape, y)

# (1024,) tf.Tensor(4, shape=(), dtype=int64)
# (1024,) tf.Tensor(2, shape=(), dtype=int64)
# (1024,) tf.Tensor(0, shape=(), dtype=int64)
# (1024,) tf.Tensor(3, shape=(), dtype=int64)
# (1024,) tf.Tensor(0, shape=(), dtype=int64)
# (1024,) tf.Tensor(0, shape=(), dtype=int64)
# (1024,) tf.Tensor(0, shape=(), dtype=int64)
# (1024,) tf.Tensor(3, shape=(), dtype=int64)
# (1024,) tf.Tensor(1, shape=(), dtype=int64)
# (1024,) tf.Tensor(3, shape=(), dtype=int64)

numpyにしたい

TensorObject.numpy()でnumpyの世界にもってこれます

x.numpy()
# array([0.62607784, 0.52501669, 0.60375316, ..., 0.82408268, 0.24436969,
#        0.61117067])

batch sizeを指定して取得できるようにしたい

ディープラーニングで利用するなら、batch sizeを指定してデータを取り出したいですよね.

# batchサイズを指定して取り出したい
train_data_batch = train_data_map.batch(32)

すると、さっきと同様イテレートしてみると結果が変わります.

# take(10)してみる
for x, y in train_data_batch.take(10):
  print(x.shape, y.shape)

# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)
# (32, 1024) (32,)

ドキュメントに書いてあるのに動かない

www.tensorflow.org

ドキュメントでは使えるような雰囲気だけどなんでじゃろ???

dataset1 = tf.data.Dataset.from_tensor_slices(tf.random.uniform([4, 10]))
print(dataset1.output_shapes)  # エラーになる.  AttributeError: 'TensorSliceDataset' object has no attribute 'output_types'

.take(n) しなくても確認できる方法がほしい.

学習するとき

# batch_sizeで取り出せるので、あとはループするだけ
model = lambda x: np.random.randint(0, 5, (32,))  # 構築したモデルと想定

for x, y in train_data_batch:
    predicted = model(x)
    
    # predictedとyで正答率を確認する...etc
    # ...
    

# test_data_batchは作っていないけどtrain側と一緒である
# for x, y in test_data_batch

雑感

他にも、TFRecode形式で保存されているデータ、テキストデータ、csvデータなど読み出す手法が書いてあったので、やっぱりドキュメントよんだほうがいいと思います.