Home > OS >  TensorFlow | create image dataset, labelled by filename
TensorFlow | create image dataset, labelled by filename

Time:04-04

Im trying to create Tensorflow dataset to train my model. I have a folder full of tagged photos, tagging is part of the files names.

do you have a reasonable way to load the dataset for training without splitting it to different directories?

example: for files:

  • ./dataset/path/img0_cat.bmp
  • ./dataset/path/img1_dog.bmp
  • ./dataset/path/img2_horse.bmp
  • ./dataset/path/img3_cat.bmp
  • ./dataset/path/img4_dog.bmp
  • ./dataset/path/img5_horse.bmp
  • ./dataset/path/img6_dog.bmp
  • ./dataset/path/img7_cat.bmp
  • ./dataset/path/img8_horse.bmp
  • ./dataset/path/img9_cat.bmp
  • ./dataset/path/img10_dog.bmp

expected output: tf.Dataset labeled as one hot for (cat, dog, horse)

thanks

CodePudding user response:

You can try assigning an ID to each path and gather paths based on whatever IDs you're using on your training set.

If you're using Tensorflow, the Dataset documentation has informative methods in loading data. Specifically,

dataset_dog = tf.data.Dataset.list_files("./dataset/path/*dog.bmp)

CodePudding user response:

here is the whole enchilada. I prefer to use pandas datasets along with the ImageDataGenerator.flow_from_dataframe because it is flexible. I created a directory single with 10 images of cranes and 10 images of albaross. Filenames are of the form 0_crane.jpf, 1_crane.jpg etc ... 10_albatross, 11_albatross ..... Code below process this directory. Create a dataframe df, then splits it into a train_df, valid_df and a test_df. Then 3 image data generators are created for train_gen, test_gen and valid_gen. I used a standard model I usually use and trained the model. Then evaluated the test ste with 100% accuracy. Code is below

import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Activation,Dropout,Conv2D, MaxPooling2D,BatchNormalization
from tensorflow.keras.optimizers import Adam, Adamax
from tensorflow.keras.metrics import categorical_crossentropy
from tensorflow.keras import regularizers
from tensorflow.keras.models import Model

sdir = r'c:\temp\single'
filepaths=[]
labels=[]
flist=os.listdir(sdir)
for f in flist:
    fpath=os.path.join(sdir,f)   
    filepaths.append(fpath)
    index1=f.rfind('_') 1
    index2=f.rfind('.')    
    klass=f[index1:index2]     
    labels.append(klass)
Fseries=pd.Series(filepaths, name='filepaths')
Lseries=pd.Series(labels, name='labels')
df=pd.concat([Fseries, Lseries], axis=1)
# now you can use train_test_split to create a train_df, a test_df and a valid_df
trsplit=.8
vsplit=.1
dsplit=vsplit/(1-trsplit)
train_df, dummy_df=train_test_split (df, train_size=trsplit, shuffle=True, random_state=123, stratify=df['labels'])
valid_df, test_df= train_test_split(dummy_df, train_size=dsplit, shuffle=True, random_state=123, stratify =dummy_df['labels'])
print ('train_df length: ', len(train_df), ' test_df length: ', len(test_df) ,'  valid_df length: ', len(valid_df))

# create a train_gen,  a valid_gen and a test_gen
# for trgen you can specify augmentations like horizontal_flip, vertical_flip etc
img_size=(224,224)
batch_size=16
trgen=ImageDataGenerator(horizontal_flip=True,rotation_range=20, width_shift_range=.2,
                                  height_shift_range=.2, zoom_range=.2   )
tvgen=ImageDataGenerator()
train_gen=trgen.flow_from_dataframe(train_df, x_col='filepaths', y_col='labels',target_size=img_size,
                                   class_mode='categorical', color_mode='rgb', shuffle=True, batch_size=batch_size)
valid_gen=tvgen.flow_from_dataframe(valid_df, x_col='filepaths', y_col='labels',target_size=img_size,
                                   class_mode='categorical', color_mode='rgb', shuffle=False, batch_size=2)
test_gen=tvgen.flow_from_dataframe(test_df, x_col='filepaths', y_col='labels',target_size=img_size,
                                   class_mode='categorical', color_mode='rgb', shuffle=False, batch_size=2)
train_files=train_gen.filenames
classes=list(train_gen.class_indices.keys())
class_count=len(classes)
labels=train_gen.labels
images, labels=next(train_gen)
plt.figure(figsize=(20, 12))
for i in range (len(images)):
    plt.subplot(4,4, i 1) 
    index=np.argmax(labels[i])
    class_name=classes[index]
    plt.title(class_name, color='yellow', fontsize=18)   
    plt.axis('off')
    plt.imshow(images[i]/255)
plt.show()
# build a model
img_shape=(img_size[0], img_size[1], 3)
model_name='EfficientNetB5'
base_model=tf.keras.applications.efficientnet.EfficientNetB5(include_top=False, weights="imagenet",input_shape=img_shape, pooling='max') 
# Note you are always told NOT to make the base model trainable initially- that is WRONG you get better results leaving it trainable
base_model.trainable=True
x=base_model.output
x=BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
x = Dense(1024, kernel_regularizer = regularizers.l2(l = 0.016),activity_regularizer=regularizers.l1(0.006),
                bias_regularizer=regularizers.l1(0.006) ,activation='relu')(x)
x=Dropout(rate=.3, seed=123)(x)
x = Dense(128, kernel_regularizer = regularizers.l2(l = 0.016),activity_regularizer=regularizers.l1(0.006),
                bias_regularizer=regularizers.l1(0.006) ,activation='relu')(x)
x=Dropout(rate=.45, seed=123)(x)        
output=Dense(class_count, activation='softmax')(x)
model=Model(inputs=base_model.input, outputs=output)
lr=.001 # start with this learning rate
model.compile(Adamax(learning_rate=lr), loss='categorical_crossentropy', metrics=['accuracy']) 

epochs=5
history=model.fit(x=train_gen,  epochs=epochs, verbose=1,  validation_data=valid_gen,
               validation_steps=None,  shuffle=False,  initial_epoch=0)

loss, acc =model.evaluate(test_gen)
print (' accuracy on test set is: ', acc* 100, '%')
  • Related