🌐 breed_recognition2.ipynb
📑 Deep Learning. Practice Project 5_0:
Processing & Classification of Horse Breeds` Images
✒️ Code Modules, Helpful Functions, & Settings
xxxxxxxxxx
#!python3 -m pip install tensorflow==2.6.0 \
#--user --quiet --no-warn-script-location
#!python3 -m pip install torch==1.8.0 \
#--user --quiet --no-warn-script-location
!python3 -m pip install torchvision==0.9.0 \
--user --quiet --no-warn-script-location
path='/home/sc_work/.sage/local/lib/python3.9/site-packages'
import os,h5py,urllib,sys,warnings
warnings.filterwarnings('ignore'); sys.path.append(path)
import torch,pandas as pd,numpy as np
import tensorflow as tf,pylab as pl
import tensorflow.keras.layers as tkl
import tensorflow.keras.callbacks as tkc
from torch.utils.data import DataLoader as tdl
from torch.utils.data import Dataset as tds
from torchvision import transforms,utils,models
import torch.nn.functional as tnnf,torch.nn as tnn
from IPython.core.magic import register_line_magic
file_path='https://raw.githubusercontent.com/'+\
'OlgaBelitskaya/data_kitchen/main/'
file_name='HorseBreeds160.h5'
dev=torch.device(
'cuda:0' if torch.cuda.is_available() else 'cpu')
img_size=int(64)
✒️ Data Loading
xxxxxxxxxx
def get_file(file_path,file_name):
input_file=urllib.request.urlopen(file_path+file_name)
output_file=open(file_name,'wb')
output_file.write(input_file.read())
output_file.close(); input_file.close()
get_file(file_path,file_name)
with h5py.File(file_name,'r') as f:
keys=list(f.keys())
pretty_print(html(
'<p>file keys: '+', '.join(keys)+'</p>'))
images=np.array(f[keys[0]])
images=tf.image.resize(images,[img_size,img_size]).numpy()
labels=np.array(f[keys[1]])
names=[el.decode('utf-8')for el in f[keys[2]]]
f.close()
✒️ Data Processing
xxxxxxxxxx
N=labels.shape[0]; n=int(.1*N)
num_classes=len(names); start=int(100)
shuffle_ids=np.arange(N)
np.random.RandomState(12).shuffle(shuffle_ids)
images=images[shuffle_ids]; labels=labels[shuffle_ids]
x_test,x_valid,x_train=images[:n],images[n:2*n],images[2*n:]
y_test,y_valid,y_train=labels[:n],labels[n:2*n],labels[2*n:]
df=pd.DataFrame(
[[x_train.shape,x_valid.shape,x_test.shape],
[x_train.dtype,x_valid.dtype,x_test.dtype],
[y_train.shape,y_valid.shape,y_test.shape],
[y_train.dtype,y_valid.dtype,y_test.dtype]],
columns=['train','valid','test'],
index=['image shape','image type','label shape','label type'])
def display_imgs(images,labels,names,start):
fig=pl.figure(figsize=(6,3)); n=randint(0,start-1)
for i in range(n,n+6):
ax=fig.add_subplot(2,3,i-n+1,xticks=[],yticks=[])
ax.set_title(
names[labels[i]],color='slategray',
fontdict={'fontsize':'large'})
ax.imshow((images[i]))
pl.tight_layout(); pl.show()
display_imgs(images,labels,names,start); display(df)
xxxxxxxxxx
class TData(tds):
def __init__(self,x,y):
self.x=torch.tensor(x,dtype=torch.float32)
self.y=torch.tensor(y,dtype=torch.int32)
def __getitem__(self,index):
img,lbl=self.x[index],self.y[index]
return img,lbl
def __len__(self):
return self.y.shape[0]
batch_size2=int(6)
n_train=batch_size2*(x_train.shape[0]//batch_size2)
x_train2=np.transpose(x_train,(0,3,1,2))[:n_train]
print(x_train2.mean(),x_train2.std())
n_valid=batch_size2*(x_valid.shape[0]//batch_size2)
x_valid2=np.transpose(x_valid,(0,3,1,2))[:n_valid]
n_test=batch_size2*(x_test.shape[0]//batch_size2)
x_test2=np.transpose(x_test,(0,3,1,2))[:n_test]
random_seed=23
train2=TData(x_train2,y_train[:n_train])
valid2=TData(x_valid2,y_valid[:n_valid])
test2=TData(x_test2,y_test[:n_test])
dataloaders={'train':tdl(dataset=train2,shuffle=True,
batch_size=batch_size2),
'valid':tdl(dataset=valid2,shuffle=True,
batch_size=batch_size2),
'test':tdl(dataset=test2,shuffle=True,
batch_size=batch_size2)}
del train2,valid2,test2
def display_data_imgs(data):
global names
for images,labels in dataloaders[data]:
print('Image dimensions: %s'%str(images.shape))
print('Label dimensions: %s'%str(labels.shape))
images=[np.transpose(images[i],(1,2,0))
for i in range(len(images))]
display_imgs(images,labels,names,int(1))
break
%display_data_imgs valid
✒️ Keras
xxxxxxxxxx
def kmodel(leaky_alpha,num_classes,img_size):
model=tf.keras.Sequential()
model.add(tkl.Conv2D(int(32),(int(5),int(5)),padding='same',
input_shape=(img_size,img_size,int(3))))
model.add(tkl.LeakyReLU(alpha=leaky_alpha))
model.add(tkl.MaxPooling2D(pool_size=(int(2),int(2))))
model.add(tkl.Dropout(float(.25)))
model.add(tkl.Conv2D(int(96),(int(5),int(5))))
model.add(tkl.LeakyReLU(alpha=leaky_alpha))
model.add(tkl.MaxPooling2D(pool_size=(int(2),int(2))))
model.add(tkl.Dropout(float(.25)))
model.add(tkl.GlobalMaxPooling2D())
model.add(tkl.Dense(int(512)))
model.add(tkl.LeakyReLU(alpha=leaky_alpha))
model.add(tkl.Dropout(float(.5)))
model.add(tkl.Dense(num_classes))
model.add(tkl.Activation('softmax'))
model.compile(loss='sparse_categorical_crossentropy',
optimizer='nadam',metrics=['accuracy'])
return model
kmodel=kmodel(float(.005),num_classes,img_size)
xxxxxxxxxx
fw='/tmp/checkpoint'
early_stopping=tkc.EarlyStopping(
monitor='val_loss',patience=int(20),verbose=int(2))
checkpointer=tkc.ModelCheckpoint(
filepath=fw,verbose=int(0),save_weights_only=True,
monitor='val_accuracy',mode='max',save_best_only=True)
lr_reduction=tkc.ReduceLROnPlateau(
monitor='val_loss',patience=int(5),
verbose=int(0),factor=float(.8))
history=kmodel.fit(
x_train,y_train,epochs=int(4),batch_size=int(16),verbose=int(2),
validation_data=(x_valid,y_valid),
callbacks=[checkpointer,early_stopping,lr_reduction])
xxxxxxxxxx
def keras_history_plot(fit_history,fig_size=8,color='#348ABD'):
keys=list(fit_history.history.keys())
list_history=[fit_history.history[keys[i]]
for i in range(len(keys))]
dfkeys=pd.DataFrame(list_history).T
dfkeys.columns=keys
fig=pl.figure(figsize=(fig_size,fig_size//2))
ax1=fig.add_subplot(2,1,1)
dfkeys.iloc[:,[int(0),int(2)]].plot(
ax=ax1,color=['slategray',color],grid=True)
ax2=fig.add_subplot(2,1,2)
dfkeys.iloc[:,[int(1),int(3)]].plot(
ax=ax2,color=['slategray',color],grid=True)
pl.tight_layout(); pl.show()
keras_history_plot(history); del history
xxxxxxxxxx
kmodel.load_weights(fw)
print(kmodel.evaluate(x_test,y_test,verbose=int(0)))
y_test_predict=np.argmax(kmodel.predict(x_test),axis=-1)
os.remove(fw)
✒️ PyTorch
xxxxxxxxxx
class FilterResponseNorm(tnn.Module):
def __init__(self,num_features,eps=float(1e-6)):
super(FilterResponseNorm,self).__init__()
self.register_parameter('beta',\
tnn.Parameter(torch.empty([int(1),num_features,
int(1),int(1)]).normal_()))
self.register_parameter('gamma',\
tnn.Parameter(torch.empty([int(1),num_features,
int(1),int(1)]).normal_()))
self.register_parameter('tau',\
tnn.Parameter(torch.empty([int(1),num_features,
int(1),int(1)]).normal_()))
self.eps=torch.Tensor([eps])
def forward(self,x):
n,c,h,w=x.size()
self.eps=self.eps.to(self.tau.device)
nu2=torch.mean(x.pow(int(2)),(int(2),int(3)),keepdims=True)
x=x*torch.rsqrt(nu2+torch.abs(self.eps))
return torch.max(self.gamma*x+self.beta,self.tau)
def convfrn(x,y,k,s,p):
return tnn.Sequential(
tnn.Conv2d(x,y,kernel_size=k,stride=s,padding=p),\
FilterResponseNorm(y))
class FRN_NNinNN(tnn.Module):
def __init__(self,num_classes):
super(FRN_NNinNN,self).__init__()
self.num_classes=num_classes
d=int(192); d2=int(256)
self.classifier=tnn.Sequential(
convfrn(int(3),d,int(5),int(1),int(2)),
# convfrn(d,d,int(1),int(1),int(0)),
convfrn(d,d2,int(1),int(1),int(0)),
tnn.MaxPool2d(kernel_size=int(3),
stride=int(2),padding=int(1)),
tnn.Dropout(float(.5)),
convfrn(d2,d,int(5),int(1),int(2)),
# convfrn(d,d,int(1),int(1),int(0)),
convfrn(d,d,int(1),int(1),int(0)),
tnn.AvgPool2d(kernel_size=int(3),
stride=int(2),padding=int(1)),
tnn.Dropout(float(.5)),
convfrn(d,d,int(3),int(1),int(1)),
convfrn(d,d,int(1),int(1),int(0)),
tnn.Conv2d(d,self.num_classes,kernel_size=int(1),
stride=int(1),padding=int(0)),
tnn.ReLU(),
tnn.AvgPool2d(kernel_size=int(16),
stride=int(1),padding=int(0)))
def forward(self,x):
x=self.classifier(x)
logits=x.view(x.size(int(0)),self.num_classes)
probs=torch.softmax(logits,dim=int(1))
return logits,probs
xxxxxxxxxx
def model_acc(model,data_loader):
correct_preds,num_examples=int(0),int(0)
for features,targets in data_loader:
features=features.to(dev)
targets=targets.to(dev).long()
logits,probs=model(features)
_,pred_labels=torch.max(logits,int(1))
num_examples+=targets.size(int(0))
correct_preds+=(pred_labels==targets).sum()
return correct_preds.float()/num_examples*int(100)
def epoch_loss(model,data_loader):
model.eval()
curr_loss,num_examples=float(0.),int(0)
with torch.no_grad():
for features,targets in data_loader:
features=features.to(dev)
targets=targets.to(dev).long()
logits,probs=model(features)
loss=tnnf.cross_entropy(
logits,targets,reduction='sum')
num_examples+=targets.size(int(0))
curr_loss+=loss
return curr_loss/num_examples
xxxxxxxxxx
def train_run(epochs):
epochs=int(epochs)
st1='epoch: %03d/%03d || batch: %03d/%03d || cost: %.4f'
for epoch in range(epochs):
tmodel.train()
for batch_ids,(features,targets) \
in enumerate(dataloaders['train']):
features=features.to(dev)
targets=targets.to(dev).long()
logits,probs=tmodel(features)
cost=tnnf.cross_entropy(logits,targets)
optimizer.zero_grad(); cost.backward()
optimizer.step()
if not batch_ids%int(20):
print(st1%(epoch+int(1),epochs,batch_ids,
len(dataloaders['train']),cost))
tmodel.eval()
with torch.set_grad_enabled(False):
print('epoch: %03d/%03d'%(epoch+int(1),epochs))
print('valid acc/loss: %.2f%%/%.2f'%\
(model_acc(tmodel,dataloaders['valid']),
epoch_loss(tmodel,dataloaders['valid'])))
torch.manual_seed(random_seed); learning_rate=float(.0001)
tmodel=FRN_NNinNN(num_classes)
tmodel.to(dev)
optimizer=torch.optim.Adam(tmodel.parameters(),lr=learning_rate)
%train_run 1
xxxxxxxxxx
tmodel.eval()
with torch.set_grad_enabled(False):
print('test acc: %.2f%%'%model_acc(tmodel,dataloaders['test']))
✒️ Models` Predictions
xxxxxxxxxx
fig=pl.figure(figsize=(6,3))
randch=np.random.choice(x_test.shape[0],size=6,replace=False)
for i,idx in enumerate(randch):
ax=fig.add_subplot(2,3,i+1,xticks=[],yticks=[])
ax.imshow(np.squeeze(x_test[idx]))
pred_idx=y_test_predict[idx]; true_idx=y_test[idx]
ax.set_title('{} \n({})'.format(names[pred_idx],names[true_idx]),
color=('#aaf' if pred_idx==true_idx else '#faa'))
pl.tight_layout(); pl.show()
xxxxxxxxxx
def show_image(img):
npimg=img.numpy(); tr=(1,2,0)
pl.figure(figsize=(6,2))
pl.imshow(np.transpose(npimg,tr))
pl.xticks([]); pl.tight_layout(); pl.show()
with torch.no_grad():
for i,(images,labels) in enumerate(dataloaders['test']):
show_image(utils.make_grid(images[:3]))
print('\ntrue labels: ',
''.join('%18s'%names[labels[j]] for j in range(3)))
images=images.to(dev)
labels=labels.to(dev).long()
logits,probs=tmodel(images)
_,preds=torch.max(logits,int(1))
print('\npredictions: ',
''.join('%18s'%names[preds[j]] for j in range(3)))
if i==1: break