Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tensorflow
GitHub Repository: tensorflow/docs-l10n
Path: blob/master/site/ko/tutorials/load_data/csv.ipynb
25118 views
Kernel: Python 3
#@title Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License.

CSV 데이터 λ‘œλ“œν•˜κΈ°

이 νŠœν† λ¦¬μ–Όμ€ TensorFlowμ—μ„œ CSV 데이터λ₯Ό μ‚¬μš©ν•˜λŠ” 방법에 λŒ€ν•œ 예제λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같이 두 κ°€μ§€ μ£Όμš” λ‚΄μš©μ΄ μžˆμŠ΅λ‹ˆλ‹€.

  1. Loading the data off disk

  2. Pre-processing it into a form suitable for training.

이 νŠœν† λ¦¬μ–Όμ€ λ‘œλ”©μ— 쀑점을 두며 μ „μ²˜λ¦¬μ— λŒ€ν•œ λͺ‡ κ°€μ§€ λΉ λ₯Έ 예λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. μ „μ²˜λ¦¬ 츑면에 λŒ€ν•΄ μžμ„Ένžˆ μ•Œμ•„λ³΄λ €λ©΄ μ „μ²˜λ¦¬ λ ˆμ΄μ–΄ μž‘μ—… κ°€μ΄λ“œ 및 Keras μ „μ²˜λ¦¬ λ ˆμ΄μ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬μ‘°ν™”λœ 데이터 λΆ„λ₯˜ νŠœν† λ¦¬μ–Όμ„ ν™•μΈν•˜μ„Έμš”.

μ„€μ •ν•˜κΈ°

import pandas as pd import numpy as np # Make numpy values easier to read. np.set_printoptions(precision=3, suppress=True) import tensorflow as tf from tensorflow.keras import layers

인메λͺ¨λ¦¬ 데이터

μž‘μ€ 크기의 CSV λ°μ΄ν„°μ„ΈνŠΈλ₯Ό μ‚¬μš©ν•˜μ—¬ TensorFlow λͺ¨λΈμ„ ν›ˆλ ¨μ‹œν‚€λŠ” κ°€μž₯ κ°„λ‹¨ν•œ 방법은 이λ₯Ό λ©”λͺ¨λ¦¬μ— pandas Dataframe λ˜λŠ” NumPy λ°°μ—΄λ‘œ λ‘œλ“œν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

비ꡐ적 κ°„λ‹¨ν•œ μ˜ˆλŠ” 전볡 λ°μ΄ν„°μ„ΈνŠΈμž…λ‹ˆλ‹€.

  • λ°μ΄ν„°μ„ΈνŠΈμ˜ 크기가 μž‘μŠ΅λ‹ˆλ‹€.

  • λͺ¨λ“  μž…λ ₯ νŠΉμ„±μ€ λͺ¨λ‘ μ œν•œλœ λ²”μœ„μ˜ 뢀동 μ†Œμˆ˜μ  κ°’μž…λ‹ˆλ‹€.

λ‹€μŒμ€ Pandas DataFrame에 데이터λ₯Ό λ‹€μš΄λ‘œλ“œν•˜λŠ” λ°©λ²•μž…λ‹ˆλ‹€.

abalone_train = pd.read_csv( "https://storage.googleapis.com/download.tensorflow.org/data/abalone_train.csv", names=["Length", "Diameter", "Height", "Whole weight", "Shucked weight", "Viscera weight", "Shell weight", "Age"]) abalone_train.head()

이 λ°μ΄ν„°μ„ΈνŠΈμ—λŠ” λ°”λ‹€ κ³ λ“±λ₯˜μ˜ 일쒅인 전볡 μΈ‘μ •κ°’ μ„ΈνŠΈκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

an abalone shell

β€œμ „λ³΅ κ»μ§ˆβ€ (Nicki Dugan Pogue 제곡, CC BY-SA 2.0)

이 데이터 μ„ΈνŠΈμ˜ λͺ…λͺ©μƒ μž‘μ—…μ€ λ‹€λ₯Έ μΈ‘μ •κ°’μœΌλ‘œλΆ€ν„° λ‚˜μ΄λ₯Ό μ˜ˆμΈ‘ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ λ‹€μŒκ³Ό 같이 ν›ˆλ ¨μ„ μœ„ν•΄ νŠΉμ„±κ³Ό λ ˆμ΄λΈ”μ„ λΆ„λ¦¬ν•©λ‹ˆλ‹€.

abalone_features = abalone_train.copy() abalone_labels = abalone_features.pop('Age')

이 λ°μ΄ν„°μ„ΈνŠΈμ—μ„œλŠ” λͺ¨λ“  νŠΉμ„±μ„ λ™μΌν•˜κ²Œ μ·¨κΈ‰ν•©λ‹ˆλ‹€. λ‹€μŒκ³Ό 같이 νŠΉμ„±μ„ 단일 NumPy λ°°μ—΄λ‘œ λ¬ΆμŠ΅λ‹ˆλ‹€.

abalone_features = np.array(abalone_features) abalone_features

λ‹€μŒμœΌλ‘œ, νšŒκ·€ λͺ¨λΈλ‘œ λ‚˜μ΄λ₯Ό μ˜ˆμΈ‘ν•©λ‹ˆλ‹€. μž…λ ₯ ν…μ„œκ°€ ν•˜λ‚˜λ§Œ μžˆμœΌλ―€λ‘œ μ—¬κΈ°μ—μ„œλŠ” keras.Sequential λͺ¨λΈμ΄λ©΄ μΆ©λΆ„ν•©λ‹ˆλ‹€.

abalone_model = tf.keras.Sequential([ layers.Dense(64), layers.Dense(1) ]) abalone_model.compile(loss = tf.keras.losses.MeanSquaredError(), optimizer = tf.keras.optimizers.Adam())

ν•΄λ‹Ή λͺ¨λΈμ„ ν›ˆλ ¨ν•˜λ €λ©΄ νŠΉμ„±κ³Ό λ ˆμ΄λΈ”μ„ Model.fit둜 μ „λ‹¬ν•©λ‹ˆλ‹€.

abalone_model.fit(abalone_features, abalone_labels, epochs=10)

μ§€κΈˆκΉŒμ§€ CSV 데이터λ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λΈμ„ ν›ˆλ ¨ν•˜λŠ” κ°€μž₯ 기본적인 방법을 λ³΄μ•˜μŠ΅λ‹ˆλ‹€. λ‹€μŒμœΌλ‘œ 숫자 열을 μ •κ·œν™”ν•˜κΈ° μœ„ν•΄ μ „μ²˜λ¦¬λ₯Ό μ μš©ν•˜λŠ” 방법을 λ°°μ›λ‹ˆλ‹€.

κΈ°λ³Έ μ „μ²˜λ¦¬

λͺ¨λΈμ— λŒ€ν•œ μž…λ ₯을 μ •κ·œν™”ν•˜λ©΄ μ’‹μŠ΅λ‹ˆλ‹€. Keras μ „μ²˜λ¦¬ λ ˆμ΄μ–΄λŠ” 이 μ •κ·œν™”λ₯Ό λͺ¨λΈμ— λΉŒλ“œν•˜λŠ” νŽΈλ¦¬ν•œ 방법을 μ œκ³΅ν•©λ‹ˆλ‹€.

tf.keras.layers.Normalization λ ˆμ΄μ–΄λŠ” 각 μ—΄μ˜ 평균과 뢄산을 미리 κ³„μ‚°ν•˜κ³  이λ₯Ό μ‚¬μš©ν•˜μ—¬ 데이터λ₯Ό μ •κ·œν™”ν•©λ‹ˆλ‹€.

λ¨Όμ € λ ˆμ΄μ–΄λ₯Ό λ§Œλ“­λ‹ˆλ‹€.

normalize = layers.Normalization()

그런 λ‹€μŒ Normalization.adapt λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ •κ·œν™” λ ˆμ΄μ–΄λ₯Ό 데이터에 맞게 μ‘°μ •ν•©λ‹ˆλ‹€.

μ°Έκ³ : PreprocessingLayer.adapt λ©”μ„œλ“œμ™€ ν•¨κ»˜ ν›ˆλ ¨ λ°μ΄ν„°λ§Œ μ‚¬μš©ν•˜κ³  검증 λ˜λŠ” ν…ŒμŠ€νŠΈ λ°μ΄ν„°λŠ” μ‚¬μš©ν•˜μ§€ λ§ˆμ„Έμš”.

normalize.adapt(abalone_features)

그런 λ‹€μŒ λͺ¨λΈμ—μ„œ μ •κ·œν™” λ ˆμ΄μ–΄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

norm_abalone_model = tf.keras.Sequential([ normalize, layers.Dense(64), layers.Dense(1) ]) norm_abalone_model.compile(loss = tf.keras.losses.MeanSquaredError(), optimizer = tf.keras.optimizers.Adam()) norm_abalone_model.fit(abalone_features, abalone_labels, epochs=10)

ν˜Όν•© 데이터 μœ ν˜•

The "Titanic" dataset contains information about the passengers on the Titanic. The nominal task on this dataset is to predict who survived.

The Titanic

Image from Wikimedia

The raw data can easily be loaded as a Pandas DataFrame, but is not immediately usable as input to a TensorFlow model.

titanic = pd.read_csv("https://storage.googleapis.com/tf-datasets/titanic/train.csv") titanic.head()
titanic_features = titanic.copy() titanic_labels = titanic_features.pop('survived')

데이터 μœ ν˜•κ³Ό λ²”μœ„κ°€ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ— λ‹¨μˆœνžˆ νŠΉμ„±μ„ NumPy 배열에 μŒ“μ•„μ„œ keras.Sequential λͺ¨λΈλ‘œ 전달할 수 μ—†μŠ΅λ‹ˆλ‹€. 각 열을 κ°œλ³„μ μœΌλ‘œ μ²˜λ¦¬ν•΄μ•Ό ν•©λ‹ˆλ‹€.

ν•œ κ°€μ§€ μ˜΅μ…˜μœΌλ‘œ 데이터λ₯Ό μ˜€ν”„λΌμΈμœΌλ‘œ μ „μ²˜λ¦¬(μ›ν•˜λŠ” 도ꡬ μ‚¬μš©)ν•˜μ—¬ λ²”μ£Όν˜• 열을 숫자 μ—΄λ‘œ λ³€ν™˜ν•œ λ‹€μŒ 처리된 좜λ ₯을 TensorFlow λͺ¨λΈμ— 전달할 수 μžˆμŠ΅λ‹ˆλ‹€. 이 μ ‘κ·Ό λ°©μ‹μ˜ 단점은 λͺ¨λΈμ„ μ €μž₯ν•˜κ³  λ‚΄λ³΄λ‚΄λŠ” 경우 μ „μ²˜λ¦¬κ°€ ν•¨κ»˜ μ €μž₯λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. Keras μ „μ²˜λ¦¬ λ ˆμ΄μ–΄λŠ” λͺ¨λΈμ˜ 일뢀이기 λ•Œλ¬Έμ— 이 문제λ₯Ό ν”Όν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 μ˜ˆμ œμ—μ„œλŠ” Keras ν•¨μˆ˜ν˜• APIλ₯Ό μ‚¬μš©ν•˜μ—¬ μ „μ²˜λ¦¬ λ‘œμ§μ„ κ΅¬ν˜„ν•˜λŠ” λͺ¨λΈμ„ λΉŒλ“œν•©λ‹ˆλ‹€. ν•˜μœ„ ν΄λž˜μŠ€ν™”ν•˜μ—¬ 같은 μž‘μ—…μ„ μˆ˜ν–‰ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

ν•¨μˆ˜ν˜• APIλŠ” "κΈ°ν˜Έν™”λœ" ν…μ„œμ—μ„œ μž‘λ™ν•©λ‹ˆλ‹€. 정상적인 "μ¦‰μ‹œ(eager)" ν…μ„œμ—λŠ” 값이 μžˆμŠ΅λ‹ˆλ‹€. λŒ€μ‘°μ μœΌλ‘œ μ΄λŸ¬ν•œ "κΈ°ν˜Έν™”λœ" ν…μ„œμ—λŠ” 값이 μ—†μŠ΅λ‹ˆλ‹€. λŒ€μ‹ μ— μ‹€ν–‰λ˜λŠ” μž‘μ—…μ„ μΆ”μ ν•˜κ³  λ‚˜μ€‘μ— μ‹€ν–‰ν•  수 μžˆλŠ” 계산 ν‘œν˜„μ„ μž‘μ„±ν•©λ‹ˆλ‹€. λ‹€μŒμ€ κ°„λ‹¨ν•œ μ˜ˆμ œμž…λ‹ˆλ‹€.

# Create a symbolic input input = tf.keras.Input(shape=(), dtype=tf.float32) # Perform a calculation using the input result = 2*input + 1 # the result doesn't have a value result
calc = tf.keras.Model(inputs=input, outputs=result)
print(calc(1).numpy()) print(calc(2).numpy())

μ „μ²˜λ¦¬ λͺ¨λΈμ„ λΉŒλ“œν•˜λ €λ©΄ λ¨Όμ € CSV μ—΄μ˜ 이름 및 데이터 μœ ν˜•κ³Ό μΌμΉ˜ν•˜λŠ” κΈ°ν˜Έν™”λœ tf.keras.Input 객체 μ„ΈνŠΈλ₯Ό λΉŒλ“œν•©λ‹ˆλ‹€.

inputs = {} for name, column in titanic_features.items(): dtype = column.dtype if dtype == object: dtype = tf.string else: dtype = tf.float32 inputs[name] = tf.keras.Input(shape=(1,), name=name, dtype=dtype) inputs

μ „μ²˜λ¦¬ λ…Όλ¦¬μ˜ 첫 번째 λ‹¨κ³„λŠ” 숫자 μž…λ ₯을 ν•¨κ»˜ μ—°κ²°ν•˜κ³  이λ₯Ό μ •κ·œν™” λ ˆμ΄μ–΄λ₯Ό 톡해 μ‹€ν–‰ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

numeric_inputs = {name:input for name,input in inputs.items() if input.dtype==tf.float32} x = layers.Concatenate()(list(numeric_inputs.values())) norm = layers.Normalization() norm.adapt(np.array(titanic[numeric_inputs.keys()])) all_numeric_inputs = norm(x) all_numeric_inputs

λ‚˜μ€‘μ— μ—°κ²°ν•  수 μžˆλ„λ‘ λͺ¨λ“  κΈ°ν˜Έν™”λœ μ „μ²˜λ¦¬ κ²°κ³Όλ₯Ό μˆ˜μ§‘ν•©λ‹ˆλ‹€.

preprocessed_inputs = [all_numeric_inputs]

λ¬Έμžμ—΄ μž…λ ₯의 경우 tf.keras.layers.StringLookup ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμžμ—΄λ‘œλΆ€ν„° μ–΄νœ˜μ˜ μ •μˆ˜ 인덱슀둜 λ§€ν•‘ν•©λ‹ˆλ‹€. 그런 λ‹€μŒ tf.keras.layers.CategoryEncoding을 μ‚¬μš©ν•˜μ—¬ 인덱슀λ₯Ό λͺ¨λΈμ— μ ν•©ν•œ float32 λ°μ΄ν„°λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

tf.keras.layers.CategoryEncoding λ ˆμ΄μ–΄μ˜ κΈ°λ³Έ 섀정은 각 μž…λ ₯에 λŒ€ν•΄ 원-ν•« 벑터λ₯Ό μƒμ„±ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. tf.keras.layers.Embedding도 μž‘λ™ν•©λ‹ˆλ‹€. 이 μ£Όμ œμ— λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ μ „μ²˜λ¦¬ λ ˆμ΄μ–΄ μž‘μ—… κ°€μ΄λ“œ 및 Keras μ „μ²˜λ¦¬ λ ˆμ΄μ–΄λ₯Ό μ‚¬μš©ν•˜μ—¬ κ΅¬μ‘°ν™”λœ 데이터 λΆ„λ₯˜ νŠœν† λ¦¬μ–Όμ„ ν™•μΈν•˜μ„Έμš”.

for name, input in inputs.items(): if input.dtype == tf.float32: continue lookup = layers.StringLookup(vocabulary=np.unique(titanic_features[name])) one_hot = layers.CategoryEncoding(num_tokens=lookup.vocabulary_size()) x = lookup(input) x = one_hot(x) preprocessed_inputs.append(x)

inputs 및 preprocessed_inputs λͺ¨μŒμ„ μ‚¬μš©ν•˜μ—¬ μ „μ²˜λ¦¬λœ λͺ¨λ“  μž…λ ₯을 ν•¨κ»˜ μ—°κ²°ν•˜κ³  μ „μ²˜λ¦¬λ₯Ό μ²˜λ¦¬ν•˜λŠ” λͺ¨λΈμ„ λΉŒλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

preprocessed_inputs_cat = layers.Concatenate()(preprocessed_inputs) titanic_preprocessing = tf.keras.Model(inputs, preprocessed_inputs_cat) tf.keras.utils.plot_model(model = titanic_preprocessing , rankdir="LR", dpi=72, show_shapes=True)

이 λͺ¨λΈμ€ μž…λ ₯ μ „μ²˜λ¦¬λ§Œ ν¬ν•¨ν•©λ‹ˆλ‹€. 이λ₯Ό μ‹€ν–‰ν•˜μ—¬ 데이터에 μ–΄λ–€ 영ν–₯을 λ―ΈμΉ˜λŠ”μ§€ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€. Keras λͺ¨λΈμ€ Pandas DataFramesλ₯Ό μžλ™μœΌλ‘œ λ³€ν™˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ™œλƒν•˜λ©΄ ν•˜λ‚˜μ˜ ν…μ„œλ‘œ λ³€ν™˜ν•΄μ•Ό ν•˜λŠ”μ§€ μ•„λ‹ˆλ©΄ ν…μ„œ μ‚¬μ „μœΌλ‘œ λ³€ν™˜ν•΄μ•Ό ν•˜λŠ”μ§€κ°€ λͺ…ν™•ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. λ”°λΌμ„œ 이λ₯Ό ν…μ„œ μ‚¬μ „μœΌλ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.

titanic_features_dict = {name: np.array(value) for name, value in titanic_features.items()}

첫 번째 ν›ˆλ ¨ 예제λ₯Ό μž˜λΌμ„œ 이 μ „μ²˜λ¦¬ λͺ¨λΈλ‘œ μ „λ‹¬ν•˜λ©΄ 숫자 νŠΉμ„±κ³Ό λ¬Έμžμ—΄ 원-핫이 λͺ¨λ‘ ν•¨κ»˜ μ—°κ²°λœ 것을 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

features_dict = {name:values[:1] for name, values in titanic_features_dict.items()} titanic_preprocessing(features_dict)

이제 이 μœ„μ— λͺ¨λΈμ„ λΉŒλ“œν•©λ‹ˆλ‹€.

def titanic_model(preprocessing_head, inputs): body = tf.keras.Sequential([ layers.Dense(64), layers.Dense(1) ]) preprocessed_inputs = preprocessing_head(inputs) result = body(preprocessed_inputs) model = tf.keras.Model(inputs, result) model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), optimizer=tf.keras.optimizers.Adam()) return model titanic_model = titanic_model(titanic_preprocessing, inputs)

λͺ¨λΈμ„ ν›ˆλ ¨ν•  λ•Œ νŠΉμ„± 사전을 x둜, λ ˆμ΄λΈ”μ„ y둜 μ „λ‹¬ν•©λ‹ˆλ‹€.

titanic_model.fit(x=titanic_features_dict, y=titanic_labels, epochs=10)

μ „μ²˜λ¦¬λŠ” λͺ¨λΈμ˜ μΌλΆ€μ΄λ―€λ‘œ λͺ¨λΈμ„ μ €μž₯ν•˜κ³  λ‹€λ₯Έ 곳에 λ‹€μ‹œ λ‘œλ“œν•˜μ—¬λ„ λ™μΌν•œ κ²°κ³Όλ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

titanic_model.save('test') reloaded = tf.keras.models.load_model('test')
features_dict = {name:values[:1] for name, values in titanic_features_dict.items()} before = titanic_model(features_dict) after = reloaded(features_dict) assert (before-after)<1e-3 print(before) print(after)

tf.data μ‚¬μš©ν•˜κΈ°

이전 μ„Ήμ…˜μ—μ„œλŠ” λͺ¨λΈμ„ ν›ˆλ ¨ν•˜λŠ” λ™μ•ˆ λͺ¨λΈμ˜ λ‚΄μž₯ 데이터 μ…”ν”Œλ§ 및 λ°°μΉ˜μ— μ˜μ‘΄ν–ˆμŠ΅λ‹ˆλ‹€.

μž…λ ₯ 데이터 νŒŒμ΄ν”„λΌμΈμ„ 더 많이 μ œμ–΄ν•΄μ•Ό ν•˜κ±°λ‚˜ λ©”λͺ¨λ¦¬μ— μ‰½κ²Œ 맞좜 수 μ—†λŠ” 데이터λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 경우 tf.dataλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

더 λ§Žμ€ 예λ₯Ό 보렀면 tf.data: TensorFlow μž…λ ₯ νŒŒμ΄ν”„λΌμΈ λΉŒλ“œ κ°€μ΄λ“œλ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.

인메λͺ¨λ¦¬ λ°μ΄ν„°μ—μ„œ

CSV 데이터에 tf.dataλ₯Ό μ μš©ν•˜λŠ” 첫 번째 예제둜 λ‹€μŒ μ½”λ“œλ₯Ό κ³ λ €ν•  경우 이전 μ„Ήμ…˜μ˜ νŠΉμ„± 사전을 μˆ˜λ™μœΌλ‘œ λΆ„ν• ν•©λ‹ˆλ‹€. 각 μΈλ±μŠ€μ—λŠ” 각 νŠΉμ„±μ— λŒ€ν•΄ μ΄λŸ¬ν•œ 인덱슀λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

import itertools def slices(features): for i in itertools.count(): # For each feature take index `i` example = {name:values[i] for name, values in features.items()} yield example

이것을 μ‹€ν–‰ν•˜κ³  첫 번째 예제λ₯Ό 좜λ ₯ν•©λ‹ˆλ‹€.

for example in slices(titanic_features_dict): for name, value in example.items(): print(f"{name:19s}: {value}") break

λ©”λͺ¨λ¦¬ 데이터 λ‘œλ”μ—μ„œ κ°€μž₯ 기본적인 tf.data.Dataset은 Dataset.from_tensor_slices μƒμ„±μžμž…λ‹ˆλ‹€. 이것은 TensorFlowμ—μ„œ μœ„μ˜ slices ν•¨μˆ˜μ˜ μΌλ°˜ν™”λœ 버전을 κ΅¬ν˜„ν•˜λŠ” tf.data.Datasetλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.

features_ds = tf.data.Dataset.from_tensor_slices(titanic_features_dict)

λ‹€λ₯Έ Python iterableκ³Ό λ§ˆμ°¬κ°€μ§€λ‘œ tf.data.Dataset에 λŒ€ν•΄ λ°˜λ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

for example in features_ds: for name, value in example.items(): print(f"{name:19s}: {value}") break

from_tensor_slices ν•¨μˆ˜λŠ” λͺ¨λ“  ꡬ쑰의 μ€‘μ²©λœ 사전 λ˜λŠ” νŠœν”Œμ„ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒ μ½”λ“œλŠ” (features_dict, labels) 쌍의 λ°μ΄ν„°μ„ΈνŠΈλ₯Ό λ§Œλ“­λ‹ˆλ‹€.

titanic_ds = tf.data.Dataset.from_tensor_slices((titanic_features_dict, titanic_labels))

이 Datasetλ₯Ό μ‚¬μš©ν•˜μ—¬ λͺ¨λΈμ„ ν›ˆλ ¨ν•˜λ €λ©΄ μ΅œμ†Œν•œ 데이터λ₯Ό shuffleν•˜κ³  batch μ²˜λ¦¬ν•΄μ•Ό ν•©λ‹ˆλ‹€.

titanic_batches = titanic_ds.shuffle(len(titanic_labels)).batch(32)

features 및 labelsλ₯Ό Model.fit에 μ „λ‹¬ν•˜λŠ” λŒ€μ‹  λ°μ΄ν„°μ„ΈνŠΈλ₯Ό μ „λ‹¬ν•©λ‹ˆλ‹€.

titanic_model.fit(titanic_batches, epochs=5)

단일 νŒŒμΌλ‘œλΆ€ν„°

μ§€κΈˆκΉŒμ§€ 이 νŠœν† λ¦¬μ–Όμ€ 인메λͺ¨λ¦¬ λ°μ΄ν„°λ‘œ μž‘μ—…ν–ˆμŠ΅λ‹ˆλ‹€. tf.dataλŠ” 데이터 νŒŒμ΄ν”„λΌμΈμ„ λΉŒλ“œν•˜κΈ° μœ„ν•œ ν™•μž₯성이 λ›°μ–΄λ‚œ νˆ΄ν‚·μ΄λ©° CSV 파일 λ‘œλ“œλ₯Ό μ²˜λ¦¬ν•˜λŠ” λͺ‡ κ°€μ§€ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.

titanic_file_path = tf.keras.utils.get_file("train.csv", "https://storage.googleapis.com/tf-datasets/titanic/train.csv")

이제 νŒŒμΌμ—μ„œ CSV 데이터λ₯Ό 읽고 tf.data.Datasetλ₯Ό μž‘μ„±ν•©λ‹ˆλ‹€.

(전체 μ„€λͺ…μ„œλŠ” tf.data.experimental.make_csv_datasetλ₯Ό μ°Έμ‘°ν•˜μ„Έμš”.)

titanic_csv_ds = tf.data.experimental.make_csv_dataset( titanic_file_path, batch_size=5, # Artificially small to make examples easier to show. label_name='survived', num_epochs=1, ignore_errors=True,)

이 ν•¨μˆ˜μ—λŠ” λ§Žμ€ νŽΈλ¦¬ν•œ νŠΉμ„±μ΄ ν¬ν•¨λ˜μ–΄ μžˆμ–΄ 데이터 μž‘μ—…μ΄ μš©μ΄ν•©λ‹ˆλ‹€. μ—¬κΈ°μ—λŠ” λ‹€μŒμ΄ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

  • μ—΄ 헀더λ₯Ό 사전 ν‚€λ‘œ μ‚¬μš©.

  • 각 μ—΄μ˜ μœ ν˜•μ„ μžλ™μœΌλ‘œ κ²°μ •.

주의: tf.data.experimental.make_csv_datasetμ—μ„œ num_epochs 인수λ₯Ό μ„€μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ tf.data.Dataset의 κΈ°λ³Έ λ™μž‘μ€ 루프λ₯Ό λ¬΄ν•œνžˆ λ°˜λ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

for batch, label in titanic_csv_ds.take(1): for key, value in batch.items(): print(f"{key:20s}: {value}") print() print(f"{'label':20s}: {label}")

μ°Έκ³ : μœ„μ˜ 셀을 두 번 μ‹€ν–‰ν•˜λ©΄ λ‹€λ₯Έ κ²°κ³Όκ°€ μƒμ„±λ©λ‹ˆλ‹€. tf.data.experimental.make_csv_dataset의 κΈ°λ³Έ μ„€μ •μ—λŠ” shuffle_buffer_size=1000이 ν¬ν•¨λ˜λ©°, μ΄λŠ” 이 μž‘μ€ λ°μ΄ν„°μ„ΈνŠΈμ—λŠ” μΆ©λΆ„ν•˜μ§€λ§Œ μ‹€μ œ λ°μ΄ν„°μ„ΈνŠΈμ—λŠ” κ·Έλ ‡μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ¦‰μ‹œ 데이터 압좕을 ν’€ μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ‹€μŒμ€ λŒ€λ„μ‹œ μ£Όκ°„ κ΅ν†΅λŸ‰ λ°μ΄ν„°μ„ΈνŠΈκ°€ ν¬ν•¨λœ gzip으둜 μ••μΆ•λœ CSV νŒŒμΌμž…λ‹ˆλ‹€.

ꡐ톡 정체.

이미지 좜처: Wikimedia

traffic_volume_csv_gz = tf.keras.utils.get_file( 'Metro_Interstate_Traffic_Volume.csv.gz', "https://archive.ics.uci.edu/ml/machine-learning-databases/00492/Metro_Interstate_Traffic_Volume.csv.gz", cache_dir='.', cache_subdir='traffic')

μ••μΆ•λœ νŒŒμΌλ‘œλΆ€ν„° 직접 읽도둝 compression_type 인수λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

traffic_volume_csv_gz_ds = tf.data.experimental.make_csv_dataset( traffic_volume_csv_gz, batch_size=256, label_name='traffic_volume', num_epochs=1, compression_type="GZIP") for batch, label in traffic_volume_csv_gz_ds.take(1): for key, value in batch.items(): print(f"{key:20s}: {value[:5]}") print() print(f"{'label':20s}: {label[:5]}")

μ°Έκ³ : tf.data νŒŒμ΄ν”„λΌμΈμ—μ„œ ν•΄λ‹Ή λ‚ μ§œ-μ‹œκ°„ λ¬Έμžμ—΄μ„ νŒŒμ‹±ν•΄μ•Ό ν•˜λŠ” 경우 tfa.text.parse_time을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

캐싱

CSV 데이터λ₯Ό νŒŒμ‹±ν•˜λŠ” 데 μ•½κ°„μ˜ μ˜€λ²„ν—€λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€. μž‘μ€ 크기의 λͺ¨λΈμ˜ 경우 μ΄λ•Œ ν›ˆλ ¨ 병λͺ© ν˜„μƒμ΄ λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ‚¬μš© 사둀에 따라 CSV 데이터가 첫 epochμ—μ„œλ§Œ ꡬ문 λΆ„μ„λ˜λ„λ‘ Dataset.cache λ˜λŠ” tf.data.Dataset.snapshot을 μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

cache와 snapshot λ©”μ„œλ“œμ˜ μ£Όμš” 차이점은 cache νŒŒμΌμ€ 이λ₯Ό μƒμ„±ν•œ TensorFlow ν”„λ‘œμ„ΈμŠ€μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‹€λ§Œ, snapshot νŒŒμΌμ€ λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€μ—μ„œ 읽을 수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, traffic_volume_csv_gz_dsλ₯Ό 20번 λ°˜λ³΅ν•˜λŠ” 데 캐싱 μ—†μ΄λŠ” μ•½ 15초, 캐싱이 있으면 μ•½ 2μ΄ˆκ°€ 걸릴 수 μžˆμŠ΅λ‹ˆλ‹€.

%%time for i, (batch, label) in enumerate(traffic_volume_csv_gz_ds.repeat(20)): if i % 40 == 0: print('.', end='') print()

μ°Έκ³ : Dataset.cacheλŠ” 첫 번째 epoch의 데이터λ₯Ό μ €μž₯ν•˜κ³  μˆœμ„œλŒ€λ‘œ μž¬μƒν•©λ‹ˆλ‹€. λ”°λΌμ„œ cache λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ νŒŒμ΄ν”„λΌμΈμ˜ μ΄ˆκΈ°μ— λͺ¨λ“  μ…”ν”Œμ΄ λΉ„ν™œμ„±ν™”λ©λ‹ˆλ‹€. μ•„λž˜μ—μ„œ Dataset.shuffle은 Dataset.cache 뒀에 λ‹€μ‹œ μΆ”κ°€λ©λ‹ˆλ‹€.

%%time caching = traffic_volume_csv_gz_ds.cache().shuffle(1000) for i, (batch, label) in enumerate(caching.shuffle(1000).repeat(20)): if i % 40 == 0: print('.', end='') print()

μ°Έκ³ : tf.data.Dataset.snapshot νŒŒμΌμ€ μ‚¬μš© 쀑인 λ°μ΄ν„°μ„ΈνŠΈλ₯Ό μž„μ‹œ μ €μž₯ν•  경우 μ‚¬μš©ν•©λ‹ˆλ‹€. 이것은 μž₯κΈ° μ €μž₯을 μœ„ν•œ ν˜•μ‹μ΄ μ•„λ‹™λ‹ˆλ‹€. 파일 ν˜•μ‹μ€ λ‚΄λΆ€ μ„ΈλΆ€ μ •λ³΄λ‘œ κ°„μ£Όλ˜λ©° TensorFlow 버전 κ°„μ˜ ν˜Έν™˜μ€ 보μž₯λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

%%time snapshotting = traffic_volume_csv_gz_ds.snapshot('titanic.tfsnap').shuffle(1000) for i, (batch, label) in enumerate(snapshotting.shuffle(1000).repeat(20)): if i % 40 == 0: print('.', end='') print()

CSV 파일 λ‘œλ“œλ‘œ 인해 데이터 λ‘œλ“œκ°€ λŠλ €μ§€κ³  Dataset.cache 및 tf.data.Dataset.snapshot이 μ‚¬μš© 사둀에 μΆ©λΆ„ν•˜μ§€ μ•Šμ€ 경우, 데이터λ₯Ό 보닀 κ°„μ†Œν™”λœ ν˜•μ‹μœΌλ‘œ λ‹€μ‹œ μΈμ½”λ”©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

μ—¬λŸ¬ 파일

μ§€κΈˆκΉŒμ§€ 이 μ„Ήμ…˜μ˜ λͺ¨λ“  μ˜ˆμ œλŠ” tf.data 없이 μ‰½κ²Œ μˆ˜ν–‰ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. tf.dataλ₯Ό μ‚¬μš©ν•˜μ—¬ μ‹€μ œλ‘œ μž‘μ—…μ„ λ‹¨μˆœν™”ν•  수 μžˆλŠ” ν•œ μ˜ˆλŠ” 파일 λͺ¨μŒμ„ μ²˜λ¦¬ν•  κ²½μš°μž…λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ 문자 κΈ€κΌ΄ 이미지 λ°μ΄ν„°μ„ΈνŠΈλŠ” κΈ€κΌ΄λ‹Ή ν•˜λ‚˜μ”©, csv 파일 λͺ¨μŒμœΌλ‘œ λ°°ν¬λ©λ‹ˆλ‹€.

κΈ€κΌ΄

Pixabayμ—μ„œ Willi Heidelbachκ°€ μ œκ³΅ν•œ 이미지

λ°μ΄ν„°μ„ΈνŠΈλ₯Ό λ‹€μš΄λ‘œλ“œν•˜κ³  λ‚΄λΆ€ νŒŒμΌμ„ κ²€ν† ν•©λ‹ˆλ‹€.

fonts_zip = tf.keras.utils.get_file( 'fonts.zip', "https://archive.ics.uci.edu/ml/machine-learning-databases/00417/fonts.zip", cache_dir='.', cache_subdir='fonts', extract=True)
import pathlib font_csvs = sorted(str(p) for p in pathlib.Path('fonts').glob("*.csv")) font_csvs[:10]
len(font_csvs)

λ§Žμ€ νŒŒμΌμ„ μ²˜λ¦¬ν•  경우 glob μŠ€νƒ€μΌμ˜ file_pattern을 tf.data.experimental.make_csv_dataset ν•¨μˆ˜μ— 전달할 수 μžˆμŠ΅λ‹ˆλ‹€. 파일의 μˆœμ„œλŠ” 각 λ°˜λ³΅λ§ˆλ‹€ λ’€μ„žμž…λ‹ˆλ‹€.

num_parallel_reads 인수λ₯Ό μ‚¬μš©ν•˜μ—¬ λ³‘λ ¬λ‘œ 읽고 ν•¨κ»˜ μΈν„°λ¦¬λΈŒ μ²˜λ¦¬λ˜λŠ” 파일의 수λ₯Ό μ„€μ •ν•©λ‹ˆλ‹€.

fonts_ds = tf.data.experimental.make_csv_dataset( file_pattern = "fonts/*.csv", batch_size=10, num_epochs=1, num_parallel_reads=20, shuffle_buffer_size=10000)

μ΄λŸ¬ν•œ CSV 파일의 μ΄λ―Έμ§€λŠ” 단일 ν–‰μœΌλ‘œ ν‰λ©΄ν™”λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. μ—΄ μ΄λ¦„μ˜ ν˜•μ‹μ€ r{row}c{column}μž…λ‹ˆλ‹€. λ‹€μŒμ€ 첫 번째 λ°°μΉ˜μž…λ‹ˆλ‹€.

for features in fonts_ds.take(1): for i, (name, value) in enumerate(features.items()): if i>15: break print(f"{name:20s}: {value}") print('...') print(f"[total: {len(features)} features]")

선택 사항: νŒ¨ν‚Ή ν•„λ“œ

μ—¬λŸ¬λΆ„μ€ μ•„λ§ˆλ„ 이와 같이 λ³„λ„μ˜ 열에 μžˆλŠ” 각 ν”½μ…€λ‘œ μž‘μ—…ν•˜κ³  μ‹Άμ§€λŠ” μ•Šμ„ κ²ƒμž…λ‹ˆλ‹€. 이 λ°μ΄ν„°μ„ΈνŠΈλ₯Ό μ‚¬μš©ν•˜κΈ° 전에 픽셀을 이미지 ν…μ„œλ‘œ νŒ¨ν‚Ήν•΄μ•Ό ν•©λ‹ˆλ‹€.

λ‹€μŒμ€ 각 예제의 이미지λ₯Ό λΉŒλ“œν•˜κΈ° μœ„ν•΄ μ—΄ 이름을 νŒŒμ‹±ν•˜λŠ” μ½”λ“œμž…λ‹ˆλ‹€.

import re def make_images(features): image = [None]*400 new_feats = {} for name, value in features.items(): match = re.match('r(\d+)c(\d+)', name) if match: image[int(match.group(1))*20+int(match.group(2))] = value else: new_feats[name] = value image = tf.stack(image, axis=0) image = tf.reshape(image, [20, 20, -1]) new_feats['image'] = image return new_feats

λ°μ΄ν„°μ„ΈνŠΈμ˜ 각 λ°°μΉ˜μ— ν•΄λ‹Ή ν•¨μˆ˜λ₯Ό μ μš©ν•©λ‹ˆλ‹€.

fonts_image_ds = fonts_ds.map(make_images) for features in fonts_image_ds.take(1): break

κ²°κ³Ό 이미지λ₯Ό ν”Œλ‘―ν•©λ‹ˆλ‹€.

from matplotlib import pyplot as plt plt.figure(figsize=(6,6), dpi=120) for n in range(9): plt.subplot(3,3,n+1) plt.imshow(features['image'][..., n]) plt.title(chr(features['m_label'][n])) plt.axis('off')

ν•˜μœ„ μˆ˜μ€€ ν•¨μˆ˜

μ§€κΈˆκΉŒμ§€ 이 νŠœν† λ¦¬μ–Όμ€ csv 데이터λ₯Ό 읽기 μœ„ν•œ κ°€μž₯ 높은 μˆ˜μ€€μ˜ μœ ν‹Έλ¦¬ν‹°μ— 쀑점을 λ‘μ—ˆμŠ΅λ‹ˆλ‹€. μ‚¬μš© 사둀가 이 κΈ°λ³Έ νŒ¨ν„΄μ— λ§žμ§€ μ•ŠλŠ” 경우 κ³ κΈ‰ μ‚¬μš©μžμ—κ²Œ 도움이 될 수 μžˆλŠ” λ‹€λ₯Έ 두 κ°€μ§€ APIκ°€ μžˆμŠ΅λ‹ˆλ‹€.

  • tf.io.decode_csv: ν…μŠ€νŠΈ 쀄을 CSV μ—΄ ν…μ„œ λͺ©λ‘μœΌλ‘œ νŒŒμ‹±ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€.

  • tf.data.experimental.CsvDataset: ν•˜μœ„ μˆ˜μ€€ CSV λ°μ΄ν„°μ„ΈνŠΈ μƒμ„±μžμž…λ‹ˆλ‹€.

이 μ„Ήμ…˜μ—μ„œλŠ” tf.data.experimental.make_csv_datasetμ—μ„œ μ œκ³΅ν•˜λŠ” κΈ°λŠ₯을 λ‹€μ‹œ λ§Œλ“€μ–΄ 이 ν•˜μœ„ μˆ˜μ€€ κΈ°λŠ₯을 μ‚¬μš©ν•˜λŠ” 방법을 λ³΄μ—¬μ€λ‹ˆλ‹€.

tf.io.decode_csv

이 ν•¨μˆ˜λŠ” λ¬Έμžμ—΄ λ˜λŠ” λ¬Έμžμ—΄ λͺ©λ‘μ„ μ—΄ λͺ©λ‘μœΌλ‘œ λ””μ½”λ”©ν•©λ‹ˆλ‹€.

tf.data.experimental.make_csv_datasetκ³Ό 달리 이 ν•¨μˆ˜λŠ” μ—΄ 데이터 μœ ν˜•μ„ μΆ”μΈ‘ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 각 열에 λŒ€ν•΄ μ˜¬λ°”λ₯Έ μœ ν˜•μ˜ 값이 ν¬ν•¨λœ record_defaults λͺ©λ‘μ„ μ œκ³΅ν•˜μ—¬ μ—΄ μœ ν˜•μ„ μ§€μ •ν•©λ‹ˆλ‹€.

tf.io.decode_csvλ₯Ό μ‚¬μš©ν•˜μ—¬ 타이타닉 데이터λ₯Ό λ¬Έμžμ—΄λ‘œ 읽기 μœ„ν•΄ λ‹€μŒκ³Ό 같이 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

text = pathlib.Path(titanic_file_path).read_text() lines = text.split('\n')[1:-1] all_strings = [str()]*10 all_strings
features = tf.io.decode_csv(lines, record_defaults=all_strings) for f in features: print(f"type: {f.dtype.name}, shape: {f.shape}")

μ‹€μ œ μœ ν˜•μœΌλ‘œ νŒŒμ‹±ν•˜λ €λ©΄ ν•΄λ‹Ή μœ ν˜•μ˜ record_defaults λͺ©λ‘μ„ λ§Œλ“­λ‹ˆλ‹€.

print(lines[0])
titanic_types = [int(), str(), float(), int(), int(), float(), str(), str(), str(), str()] titanic_types
features = tf.io.decode_csv(lines, record_defaults=titanic_types) for f in features: print(f"type: {f.dtype.name}, shape: {f.shape}")

μ°Έκ³ : CSV ν…μŠ€νŠΈμ˜ κ°œλ³„ 라인보닀 λŒ€ν˜• 라인 λ°°μΉ˜μ—μ„œ tf.io.decode_csvλ₯Ό ν˜ΈμΆœν•˜λŠ” 것이 더 νš¨μœ¨μ μž…λ‹ˆλ‹€.

tf.data.experimental.CsvDataset

tf.data.experimental.CsvDataset ν΄λž˜μŠ€λŠ” tf.data.experimental.make_csv_dataset ν•¨μˆ˜μ˜ νŽΈλ¦¬ν•œ νŠΉμ„±μΈ μ—΄ 헀더 νŒŒμ‹±, μ—΄ μœ ν˜• μΆ”λ‘ , μžλ™ μ…”ν”Œλ§, 파일 인터리빙 없이 μ΅œμ†Œν•œμ˜ CSV Dataset μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€.

이 μƒμ„±μžλŠ” tf.io.decode_csv와 같은 λ°©μ‹μœΌλ‘œ record_defaultsλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

simple_titanic = tf.data.experimental.CsvDataset(titanic_file_path, record_defaults=titanic_types, header=True) for example in simple_titanic.take(1): print([e.numpy() for e in example])

μœ„μ˜ μ½”λ“œλŠ” 기본적으둜 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

def decode_titanic_line(line): return tf.io.decode_csv(line, titanic_types) manual_titanic = ( # Load the lines of text tf.data.TextLineDataset(titanic_file_path) # Skip the header row. .skip(1) # Decode the line. .map(decode_titanic_line) ) for example in manual_titanic.take(1): print([e.numpy() for e in example])

μ—¬λŸ¬ 파일

tf.data.experimental.CsvDataset을 μ‚¬μš©ν•˜μ—¬ κΈ€κΌ΄ λ°μ΄ν„°μ„ΈνŠΈλ₯Ό νŒŒμ‹±ν•˜λ €λ©΄ λ¨Όμ € record_defaults에 λŒ€ν•œ μ—΄ μœ ν˜•μ„ κ²°μ •ν•΄μ•Ό ν•©λ‹ˆλ‹€. μš°μ„  ν•œ 파일의 첫 번째 행을 κ²€μ‚¬ν•©λ‹ˆλ‹€.

font_line = pathlib.Path(font_csvs[0]).read_text().splitlines()[1] print(font_line)

처음 두 개의 ν•„λ“œλ§Œ λ¬Έμžμ—΄μ΄κ³  λ‚˜λ¨Έμ§€λŠ” μ •μˆ˜ λ˜λŠ” 뢀동 μ†Œμˆ˜μ μ΄λ©° μ‰Όν‘œλ₯Ό κ³„μ‚°ν•˜μ—¬ 총 νŠΉμ„± 수λ₯Ό 얻을 수 μžˆμŠ΅λ‹ˆλ‹€.

num_font_features = font_line.count(',')+1 font_column_types = [str(), str()] + [float()]*(num_font_features-2)

tf.data.experimental.CsvDataset μƒμ„±μžλŠ” μž…λ ₯ 파일 λͺ©λ‘μ„ κ°€μ Έμ˜¬ 수 μžˆμ§€λ§Œ 순차적으둜 μ½μŠ΅λ‹ˆλ‹€. CSV λͺ©λ‘μ˜ 첫 번째 νŒŒμΌμ€ AGENCY.csvμž…λ‹ˆλ‹€.

font_csvs[0]

λ”°λΌμ„œ 파일 λͺ©λ‘μ„ CsvDataset에 전달할 λ•Œ AGENCY.csv의 λ ˆμ½”λ“œλ₯Ό λ¨Όμ € μ½μŠ΅λ‹ˆλ‹€.

simple_font_ds = tf.data.experimental.CsvDataset( font_csvs, record_defaults=font_column_types, header=True)
for row in simple_font_ds.take(10): print(row[0].numpy())

μ—¬λŸ¬ νŒŒμΌμ„ μΈν„°λ¦¬λΈŒν•˜λ €λ©΄ Dataset.interleaveλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

CSV 파일 이름이 ν¬ν•¨λœ 초기 λ°μ΄ν„°μ„ΈνŠΈλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

font_files = tf.data.Dataset.list_files("fonts/*.csv")

μ΄λ ‡κ²Œ ν•˜λ©΄ 각 epochλ§ˆλ‹€ 파일 이름을 μ…”ν”Œν•©λ‹ˆλ‹€.

print('Epoch 1:') for f in list(font_files)[:5]: print(" ", f.numpy()) print(' ...') print() print('Epoch 2:') for f in list(font_files)[:5]: print(" ", f.numpy()) print(' ...')

interleave λ©”μ„œλ“œλŠ” μƒμœ„ Dataset의 각 μš”μ†Œλ§ˆλ‹€ ν•˜μœ„ Datasetλ₯Ό μƒμ„±ν•˜λŠ” map_funcλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

μ—¬κΈ°μ—μ„œ 파일 λ°μ΄ν„°μ„ΈνŠΈμ˜ 각 μš”μ†Œμ—μ„œ tf.data.experimental.CsvDataset을 μƒμ„±ν•˜λ €κ³  ν•©λ‹ˆλ‹€.

def make_font_csv_ds(path): return tf.data.experimental.CsvDataset( path, record_defaults=font_column_types, header=True)

μΈν„°λ¦¬λΈŒλ‘œ λ°˜ν™˜ν•œ DatasetλŠ” μ—¬λŸ¬ ν•˜μœ„ Datasetλ₯Ό μˆœν™˜ν•˜λ©° μš”μ†Œλ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. μ•„λž˜μ—μ„œ λ°μ΄ν„°μ„ΈνŠΈκ°€ cycle_length=3 μ„Έ κ°€μ§€ κΈ€κΌ΄ νŒŒμΌμ„ μˆœν™˜ν•˜λŠ” 방식을 ν™•μΈν•˜μ„Έμš”.

font_rows = font_files.interleave(make_font_csv_ds, cycle_length=3)
fonts_dict = {'font_name':[], 'character':[]} for row in font_rows.take(10): fonts_dict['font_name'].append(row[0].numpy().decode()) fonts_dict['character'].append(chr(row[2].numpy())) pd.DataFrame(fonts_dict)

곡연

이전에 tf.io.decode_csvκ°€ λ¬Έμžμ—΄ λ°°μΉ˜μ—μ„œ 싀행될 λ•Œ 더 νš¨μœ¨μ μ΄λΌλŠ” 점을 μ–ΈκΈ‰ν–ˆμŠ΅λ‹ˆλ‹€.

λŒ€ν˜• 배치 크기λ₯Ό μ‚¬μš©ν•  λ•Œ 이 사싀을 ν™œμš©ν•˜μ—¬ CSV λ‘œλ“œ μ„±λŠ₯을 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€(단, λ¨Όμ € 캐싱을 μ‹œλ„ν•΄μ•Ό 함).

λ‚΄μž₯ λ‘œλ” 20을 μ‚¬μš©ν•  경우 2048개의 예제 λ°°μΉ˜μ— μ•½ 17μ΄ˆκ°€ κ±Έλ¦½λ‹ˆλ‹€.

BATCH_SIZE=2048 fonts_ds = tf.data.experimental.make_csv_dataset( file_pattern = "fonts/*.csv", batch_size=BATCH_SIZE, num_epochs=1, num_parallel_reads=100)
%%time for i,batch in enumerate(fonts_ds.take(20)): print('.',end='') print()

ν…μŠ€νŠΈ 쀄 배치λ₯Ό decode_csv에 μ „λ‹¬ν•˜λ©΄ 더 λΉ λ₯΄κ²Œ μ•½ 5초 λ§Œμ— μ‹€ν–‰λ©λ‹ˆλ‹€.

fonts_files = tf.data.Dataset.list_files("fonts/*.csv") fonts_lines = fonts_files.interleave( lambda fname:tf.data.TextLineDataset(fname).skip(1), cycle_length=100).batch(BATCH_SIZE) fonts_fast = fonts_lines.map(lambda x: tf.io.decode_csv(x, record_defaults=font_column_types))
%%time for i,batch in enumerate(fonts_fast.take(20)): print('.',end='') print()

λŒ€κ·œλͺ¨ 배치λ₯Ό μ‚¬μš©ν•˜μ—¬ CSV μ„±λŠ₯을 λ†’μ΄λŠ” 또 λ‹€λ₯Έ μ˜ˆλŠ” κ³ΌλŒ€μ ν•©κ³Ό κ³Όμ†Œμ ν•© νŠœν† λ¦¬μ–Όμ„ μ°Έμ‘°ν•˜μ„Έμš”.

μ΄λŸ¬ν•œ μ’…λ₯˜μ˜ μ ‘κ·Ό 방식이 νš¨κ³Όκ°€ μžˆμ„ 수 μžˆμ§€λ§Œ Dataset.cache 및 tf.data.Dataset.snapshotκ³Ό 같은 λ‹€λ₯Έ μ˜΅μ…˜κ³Ό ν•¨κ»˜ 데이터λ₯Ό 보닀 κ°„μ†Œν™”λœ ν˜•μ‹μœΌλ‘œ λ‹€μ‹œ μΈμ½”λ”©ν•˜λŠ” 방법도 κ³ λ €ν•˜μ„Έμš”.