-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHand_MachineText.py
More file actions
397 lines (277 loc) · 12.7 KB
/
Copy pathHand_MachineText.py
File metadata and controls
397 lines (277 loc) · 12.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# -*- coding: utf-8 -*-
"""Copy of PersonalProjectipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1VoUMEPEMNsP7sCiazIEyONt12uvou2mQ
### CONNECT TO DRIVE FOLDER ANND MAP TO CO LAB
"""
# Mount your google drive where you've saved your assignment folder
from google.colab import drive
drive.mount('/content/gdrive')
"""### Navigate to the right Folder """
# Commented out IPython magic to ensure Python compatibility.
# %cd '/content/gdrive/MyDrive/personal_project01'
"""#### Check if you are in the right folder
"""
!ls
"""# Start Here"""
import tensorflow as tf
import os
"""## <font color='green'> OC </font> allow you to see the dirctory files
"""
os.listdir('data')
"""##<font color='green'>The code bellow: </font> make sure you won't use all your gpu and get the Out of Memory error!
"""
# avoid OOM by setting the GPU Memory Consumption Growth
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
#gpus = tf.config.experimental.list_physical_devices('CPU')
#gpus
"""
## <font color='green'> Download Dependancy : </font> cv and imagehdr TO REMOVE ANY DOGGY IMAGES
"""
import cv2
import imghdr
from matplotlib import pyplot as plt
# access a variable to hold data
data_dir = 'data'
#check DATA file if it has our files
os.listdir(data_dir)
# create an list of images extensions
image_exts = ['jpeg', 'jpg', 'bmp', 'png']
"""## <font color='yellow'> #To navigate and check the folder </font> To check the images inside the *folders*!
#if i want to check the picture in my happy folder example
##:<font color= 'blue'> os.listdir(os.path.join(data_dir, 'happy')) </font>
## To check for sad folder in data directory
## <font color='blue'> os.listdir(os.path.join(data_dir, 'sad')) </font>
"""
#if i want to check the picture in my happy folder example
#os.listdir(os.path.join(data_dir, 'happy'))
"""## <font color='yellow'> loop inside every picture : </font> go inside our directory and print happy and sad files
"""
###. Dont run this cell just for learning sake! ####
# This line will convert the pic to an array and let you open any image in the directory
img= cv2.imread(os.path.join('data','Hand', 'img1.png'))
#TO SEE THE IMG SHAPE
img.shape
#TO SHOW THE IMAGE (COLOR WILL LOOK OFF BECAUSE CV READ RBG ONLY)
plt.imshow(img)
# TO FIX THAT YOU CAN DO WILL FIX THE COLOR THIS IS WHERE from matplotlib import pyplot as plt COMES HANDY
plt.imshow(cv2.cvtColor(img,cv2.COLOR_RGB2BGR))
#TO GET READ OF THAT WEIRD LINES COMES AT THE TOP OF THE IMAGE (TO SEE THE LINE DELETE THE CODE BELOW)
plt.show()
# to access the file (ahppy, sad) in data dir
for image_class in os.listdir(data_dir):
# to go through every image in image_class(happy,sad) folders
for image in os.listdir(os.path.join(data_dir, image_class)):
#to go to specific image in every class in everyfolder in data_dir
image_path = os.path.join(data_dir, image_class, image)
try:
# check if its not a valid image
img = cv2.imread(image_path)
# check if its not a valid extention
tip = imghdr.what(image_path)
# if it is the get rid of it
if tip not in image_exts:
print(f'Image not exist in list {image_path}')
# this will allow you to delete a file
os.remove(image_path)
except Exception as e:
print(f'Issue with image {image_path}')
"""
## <font color ='red'> Load Data </font>
"""
# to start a pipline and create your own data
tf.data.Dataset
"""## <font color ='red'>"""
#import numpy and plt(previosly did it above)
import numpy as np
from matplotlib import pyplot as plt
"""# - The code below will help you to lable the picture, class,natch_size=32, img_size to (256,256) shufle them and more pretty much set them up"""
#load data build an image data set on the fly which you dont need to buld
#any img class or resize and punch of other pre process most importently it set all the image to the same size
# you can change any of the size or batch by just addeding to the code below:
# data = tf.keras.utils.image_dataset_from_directory('data', batch_size = 8 or 16 , image_size = (128,128))..etc
data = tf.keras.utils.image_dataset_from_directory('data')
# this code will pretty much iterate through all the doc and pull them as it goes and loop through the data
data_iterator = data.as_numpy_iterator()
# pull the image Get batch from the iterator
batch = data_iterator.next()
# images represented as numpy arrays
batch[0].shape
#class 1 = Machine
# class 0 = Hand
batch[1]
# using matloplib to show the pic we set it for 4 pic at the time
fig, ax = plt.subplots(ncols =4, figsize = (20,20))
for idx, img in enumerate(batch[0][:4]):
ax[idx].imshow(img.astype(int))
ax[idx].title.set_text(batch[1][idx])
"""## #2.Processing Data
"""
# scaled our data to mkae it run much faster because its between 0-1 rather than 0-255 so we devided it by 255 Play with the code to see should be set 0|1 0 for min 1 max
scaled = batch[0] / 255
scaled.max() #this should print 1.0
scaled.min() # should print 0.0
"""## 2.1 Scale Data: useful website is https://www.tensorflow.org/guide/data"""
# to apply scaling on our pipline which is the effective way to do scaling
data = data.map(lambda x,y: (x/255,y))
#give us access to data and allow us to grab the next batch
scaled_iterator = data.as_numpy_iterator()
batch = scaled_iterator.next()
batch[0].min() #try max should give you 1.0 result
# using matloplib to show the pic we set it for 4 pic at the time
# notice if we run the same code above the resut will be black image reason why because we assign img.astype(int) but we forgot that we devided by 255 so will give zero
# to fix the issue we just need to change the value of img.astype(int) to just imshow(img) instead and wolaa workes! ;)
fig, ax = plt.subplots(ncols =4, figsize = (20,20))
for idx, img in enumerate(batch[0][:4]):
ax[idx].imshow(img)
ax[idx].title.set_text(batch[1][idx])
"""## 2.2 Split Data"""
# check our data we see that we have 14 batches each one has 32 picture for the most part
len(data)
"""## The code below will do the following:
1- train_size : will train our data what it used to train our model
2- val_size : will evaluate our data while we training
3- test_size: this will come in handy at the end
1&2 will use during training while 3 after training
"""
# set our training set to 70% of the Data
train_size = int(len(data)*.7) # will set 9 batches to training
# set our validation to 20% of the Data
val_size = int(len(data)*.2)+2 # will be 4 batch which is a problem to fix we just add 1
# set our test to 10% of the Data
test_size =int(len(data)*.1) # will be 1 so to fix it we just add 1 to get all 7 baches
# so now we sum all of them to make sure we get all the batches data
train_size + test_size + val_size # sum equal 14 means we are good to go ;)
# To check the other set just run the name to see the length of it
"""## Establish you train and val & test data
"""
# check the tf website above to learn more about take and skip
# also if the data is not shuffle make sure to shuffle it before you do this.
# so this code will assign how the data will be treated
#train will take the training batch thats why we used take
train = data.take(train_size)
# val will skip first the data that been trained and take the val_size
val = data.skip(train_size).take(val_size)
# test will skip the train data and the val and deal with the rest
test = data.skip(train_size + val_size).take(test_size)
len(train) #should print 9
len(val) # should print 4
len(test) #should print 1
"""## 3.Deep Model
## 3.1 Build Deep learning Model
"""
# import the sequential api
from tensorflow.keras.models import Sequential
# bring layers conv nural network 2D, maxpooling go through to your img and condince it
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout #no need for Dropout
model = Sequential()
#adding convelutional layer and MaxPooling layer
# it has 16 filters and scan over an image and try to extrac the relevent information to make an out size 3*3 pixle and move 1 pixle
# activation: we are applying 'relu' which convert any negative value to zero # google relue activation
# input_shape this how we want our input to look like 256*256 pixle and moving 3 pixle
model.add(Conv2D(16, (3,3), 1, activation = 'relu', input_shape=(256,256,3)))
model.add(MaxPooling2D())
model.add(Conv2D(32, (3,3), 1, activation='relu'))
model.add(MaxPooling2D())
model.add(Conv2D(16, (3,3), 1, activation = 'relu'))
model.add(MaxPooling2D())
# flatten condance the width and length
model.add(Flatten())
# to get only one out put
model.add(Dense(256, activation='relu'))
# sigmoid will give us 0-1 which is Hand or Machine written text
model.add(Dense(1, activation= 'sigmoid'))
# compile the model we are using adam there as tons if other once you can just use tf.optimizers. and will show you the list of them
# losses for the binary
# we need to track the accuracy
model.compile('adam', loss=tf.losses.BinaryCrossentropy(), metrics=['accuracy'])
# check the model
model.summary()
"""## 3.2 Train"""
#create a folder abd access it 'logs'
logdir ='logs'
# to check how yor model peroform
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)
#fit our model fit is training our data , epochs= how many time the model will train, validation to check the validation of our data and then call back
# here we are training the data and see the results
# fit: training componant
# training: which will take our training data which is 9 batches 32imgs each
# epoches = how many time we will train the model
#validation = after we train the batches so we run the validation to see how the training goes
#hist = history to so how each traingand the changes on accuracy and loss (ideally: you want the loss to go down and the accuracy goes up! )
hist = model.fit(train, epochs= 20, validation_data= val, callbacks = [tensorboard_callback])
# to check the training history
hist.history
"""## 3.3 Plot Performance"""
# create a plot figure if the va_loss go up means you have over fitting
fig = plt.figure()
plt.plot(hist.history['loss'], color ='green', label = 'loss')
plt.plot(hist.history['val_loss'], color = 'orange', label ='val_loss')
fig,plt.suptitle('loss', fontsize = 20)
plt.legend(loc="upper left")
plt.show()
# now we do the same to our accuracy our model perform really well it gives 100%
fig = plt.figure()
plt.plot(hist.history['accuracy'], color ='green', label = 'accuracy')
plt.plot(hist.history['val_accuracy'], color = 'orange', label ='val_accuracy')
fig,plt.suptitle('accuracy', fontsize = 20)
plt.legend(loc="upper left")
plt.show()
"""## 4. Evaluation Performance
## 4.1 Evaluate
"""
# in order to evaluate the model
from tensorflow.keras.metrics import Precision, Recall, BinaryAccuracy
# establish instances to be able to use them
pre = Precision()
re = Recall()
acc= BinaryAccuracy()
# remember that we have only 1 batch to our test data you can check it by running this code: len(test)
for batch in test.as_numpy_iterator():
x,y = batch
yhat = model.predict(x)
pre.update_state(y,yhat)
re.update_state(y,yhat)
acc.update_state(y, yhat)
#print out the results
print(f'precision:{pre.result().numpy()}, Recall: {re.result().numpy()}, Accuracy: {acc.result().numpy()}')
"""## 4.2 Test
"""
import cv2
# we trying to test an imaage the model have not seen before so we go ahead and save a random sad or happy picture form google
img = cv2.imread('machin_test.jpeg')
#plt.imshow(img) this will make the picture look blueish to fix that:
plt.imshow(cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
plt.show()
# TO RESIZE OUR IMAGE TO (256,256)
resize = tf.image.resize(img, (256,256))
plt.imshow(resize.numpy().astype(int))
plt.show()
# here we change the size to (256,256)
#scale it
yhat = model.predict(np.expand_dims(resize/255 ,0))
yhat # if you see the model predict that its 0.947 which is close to 1 which mean happy remember up 1: happy 0:sad
# here we sit an if statment to print the result
if yhat > 0.5:
print(f'Predicted class is Machine_written')
else:
print(f'Predicted class is Hand_written')
"""#5.0 Save The Model"""
# to load all the dependancy from tensorflow
from tensorflow.keras.models import load_model
# saving the model and serialization (taking a model and serialization like zip it)
model.save(os.path.join('model', 'hand_machine_written.h5'))
# we can now reload the model
new_model = load_model(os.path.join('model', 'hand_machine_written.h5'))
#show the model
new_model
yhat_new = new_model.predict(np.expand_dims(resize/255, 0))
# here we sit an if statment to print the result
if yhat_new > 0.5:
print(f'Predicted class is Machine_written')
else:
print(f'Predicted class is Hand_written')
"""## <font color = 'green'> DONNNNEEEEEEEEEEEE HOOOOOORRAAAAAY </font> ✅"""