文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

教你使用TensorFlow2对阿拉伯语手写字符数据集进行识别

2024-12-03 03:40

关注

在本教程中,我们将使用 TensorFlow (Keras API) 实现一个用于多分类任务的深度学习模型,该任务需要对阿拉伯语手写字符数据集进行识别。

数据集下载地址:https://www.kaggle.com/mloey1/ahcd1

数据集介绍

该数据集由 60 名参与者书写的16,800 个字符组成,年龄范围在 19 至 40 岁之间,90% 的参与者是右手。

每个参与者在两种形式上写下每个字符(从“alef”到“yeh”)十次,如图 7(a)和 7(b)所示。表格以 300 dpi 的分辨率扫描。使用 Matlab 2016a 自动分割每个块以确定每个块的坐标。该数据库分为两组:训练集(每类 13,440 个字符到 480 个图像)和测试集(每类 3,360 个字符到 120 个图像)。数据标签为1到28个类别。在这里,所有数据集都是CSV文件,表示图像像素值及其相应标签,并没有提供对应的图片数据。

导入模块

  1. import numpy as np 
  2. import pandas as pd 
  3. #允许对dataframe使用display() 
  4. from IPython.display import display 
  5. # 导入读取和处理图像所需的库 
  6. import csv 
  7. from PIL import Image 
  8. from scipy.ndimage import rotate 

读取数据

  1. # 训练数据images 
  2. letters_training_images_file_path = "../input/ahcd1/csvTrainImages 13440x1024.csv" 
  3. # 训练数据labels 
  4. letters_training_labels_file_path = "../input/ahcd1/csvTrainLabel 13440x1.csv" 
  5. # 测试数据images和labels 
  6. letters_testing_images_file_path = "../input/ahcd1/csvTestImages 3360x1024.csv" 
  7. letters_testing_labels_file_path = "../input/ahcd1/csvTestLabel 3360x1.csv" 
  8.  
  9. # 加载数据 
  10. training_letters_images = pd.read_csv(letters_training_images_file_path, header=None) 
  11. training_letters_labels = pd.read_csv(letters_training_labels_file_path, header=None) 
  12. testing_letters_images = pd.read_csv(letters_testing_images_file_path, header=None) 
  13. testing_letters_labels = pd.read_csv(letters_testing_labels_file_path, header=None) 
  14.  
  15. print("%d个32x32像素的训练阿拉伯字母图像。" %training_letters_images.shape[0]) 
  16. print("%d个32x32像素的测试阿拉伯字母图像。" %testing_letters_images.shape[0]) 
  17. training_letters_images.head() 

13440个32x32像素的训练阿拉伯字母图像。3360个32x32像素的测试阿拉伯字母图像。

查看训练数据的head

 

  1. np.unique(training_letters_labels) 
  2. array([ 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], dtype=int32) 

下面需要将csv值转换为图像,我们希望展示对应图像的像素值图像。

  1. def convert_values_to_image(image_values, display=False): 
  2.     image_array = np.asarray(image_values) 
  3.     image_array = image_array.reshape(32,32).astype('uint8'
  4.     # 原始数据集被反射,因此我们将使用np.flip翻转它,然后通过rotate旋转,以获得更好的图像。 
  5.     image_array = np.flip(image_array, 0) 
  6.     image_array = rotate(image_array, -90) 
  7.     new_image = Image.fromarray(image_array) 
  8.     if display == True
  9.         new_image.show() 
  10.     return new_image 
  11. convert_values_to_image(training_letters_images.loc[0], True

 这是一个字母f。

下面,我们将进行数据预处理,主要进行图像标准化,我们通过将图像中的每个像素除以255来重新缩放图像,标准化到[0,1]

  1. training_letters_images_scaled = training_letters_images.values.astype('float32')/255 
  2. training_letters_labels = training_letters_labels.values.astype('int32'
  3. testing_letters_images_scaled = testing_letters_images.values.astype('float32')/255 
  4. testing_letters_labels = testing_letters_labels.values.astype('int32'
  5. print("Training images of letters after scaling"
  6. print(training_letters_images_scaled.shape) 
  7. training_letters_images_scaled[0:5] 

输出如下

  1. Training images of letters after scaling 
  2. (13440, 1024) 

从标签csv文件我们可以看到,这是一个多类分类问题。下一步需要进行分类标签编码,建议将类别向量转换为矩阵类型。

输出形式如下:将1到28,变成0到27类别。从“alef”到“yeh”的字母有0到27的分类号。to_categorical就是将类别向量转换为二进制(只有0和1)的矩阵类型表示

在这里,我们将使用keras的一个热编码对这些类别值进行编码。

一个热编码将整数转换为二进制矩阵,其中数组仅包含一个“1”,其余元素为“0”。

  1. from keras.utils import to_categorical 
  2.  
  3. # one hot encoding 
  4. number_of_classes = 28 
  5.  
  6. training_letters_labels_encoded = to_categorical(training_letters_labels-1, num_classes=number_of_classes) 
  7. testing_letters_labels_encoded = to_categorical(testing_letters_labels-1, num_classes=number_of_classes) 

 

  1. # (13440, 1024) 

下面将输入图像重塑为32x32x1,因为当使用TensorFlow作为后端时,Keras CNN需要一个4D数组作为输入,并带有形状(nb_samples、行、列、通道)

其中 nb_samples对应于图像(或样本)的总数,而行、列和通道分别对应于每个图像的行、列和通道的数量。

  1. # reshape input letter images to 32x32x1 
  2. training_letters_images_scaled = training_letters_images_scaled.reshape([-1, 32, 32, 1]) 
  3. testing_letters_images_scaled = testing_letters_images_scaled.reshape([-1, 32, 32, 1]) 
  4.  
  5. print(training_letters_images_scaled.shape, training_letters_labels_encoded.shape, testing_letters_images_scaled.shape, testing_letters_labels_encoded.shape) 
  6. # (13440, 32, 32, 1) (13440, 28) (3360, 32, 32, 1) (3360, 28) 

因此,我们将把输入图像重塑成4D张量形状(nb_samples,32,32,1),因为我们图像是32x32像素的灰度图像。

  1. #将输入字母图像重塑为32x32x1 
  2. training_letters_images_scaled = training_letters_images_scaled.reshape([-1, 32, 32, 1]) 
  3. testing_letters_images_scaled = testing_letters_images_scaled.reshape([-1, 32, 32, 1]) 
  4.  
  5. print(training_letters_images_scaled.shape, training_letters_labels_encoded.shape, testing_letters_images_scaled.shape, testing_letters_labels_encoded.shape) 

设计模型结构

  1. from keras.models import Sequential 
  2. from keras.layers import Conv2D, MaxPooling2D, GlobalAveragePooling2D, BatchNormalization, Dropout, Dense 
  3.  
  4. def create_model(optimizer='adam', kernel_initializer='he_normal', activation='relu'): 
  5.     # create model 
  6.     model = Sequential() 
  7.     model.add(Conv2D(filters=16, kernel_size=3, padding='same', input_shape=(32, 32, 1), kernel_initializer=kernel_initializer, activation=activation)) 
  8.     model.add(BatchNormalization()) 
  9.     model.add(MaxPooling2D(pool_size=2)) 
  10.     model.add(Dropout(0.2)) 
  11.  
  12.     model.add(Conv2D(filters=32, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation)) 
  13.     model.add(BatchNormalization()) 
  14.     model.add(MaxPooling2D(pool_size=2)) 
  15.     model.add(Dropout(0.2)) 
  16.  
  17.     model.add(Conv2D(filters=64, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation)) 
  18.     model.add(BatchNormalization()) 
  19.     model.add(MaxPooling2D(pool_size=2)) 
  20.     model.add(Dropout(0.2)) 
  21.  
  22.     model.add(Conv2D(filters=128, kernel_size=3, padding='same', kernel_initializer=kernel_initializer, activation=activation)) 
  23.     model.add(BatchNormalization()) 
  24.     model.add(MaxPooling2D(pool_size=2)) 
  25.     model.add(Dropout(0.2)) 
  26.     model.add(GlobalAveragePooling2D()) 
  27.  
  28.     #Fully connected final layer 
  29.     model.add(Dense(28, activation='softmax')) 
  30.  
  31.     # Compile model 
  32.     model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer=optimizer) 
  33.     return model 

「模型结构」

  1. model = create_model(optimizer='Adam', kernel_initializer='uniform', activation='relu'
  2. model.summary() 

 

「Keras支持在Keras.utils.vis_utils模块中绘制模型,该模块提供了使用graphviz绘制Keras模型的实用函数」

  1. import pydot 
  2. from keras.utils import plot_model 
  3.  
  4. plot_model(model, to_file="model.png", show_shapes=True
  5. from IPython.display import Image as IPythonImage 
  6. display(IPythonImage('model.png')) 

 

训练模型,使用batch_size=20来训练模型,对模型进行15个epochs阶段的训练。

  1. from keras.callbacks import ModelCheckpoint   
  2.  
  3. # 使用检查点来保存稍后使用的模型权重。 
  4. checkpointer = ModelCheckpoint(filepath='weights.hdf5', verbose=1, save_best_only=True
  5. history = model.fit(training_letters_images_scaled, training_letters_labels_encoded,validation_data=(testing_letters_images_scaled,testing_letters_labels_encoded),epochs=15, batch_size=20, verbose=1, callbacks=[checkpointer]) 

训练结果如下所示:

最后Epochs绘制损耗和精度曲线。

  1. import matplotlib.pyplot as plt 
  2.  
  3. def plot_loss_accuracy(history): 
  4.     # Loss  
  5.     plt.figure(figsize=[8,6]) 
  6.     plt.plot(history.history['loss'],'r',linewidth=3.0) 
  7.     plt.plot(history.history['val_loss'],'b',linewidth=3.0) 
  8.     plt.legend(['Training loss''Validation Loss'],fontsize=18) 
  9.     plt.xlabel('Epochs ',fontsize=16) 
  10.     plt.ylabel('Loss',fontsize=16) 
  11.     plt.title('Loss Curves',fontsize=16) 
  12.  
  13.     # Accuracy  
  14.     plt.figure(figsize=[8,6]) 
  15.     plt.plot(history.history['accuracy'],'r',linewidth=3.0) 
  16.     plt.plot(history.history['val_accuracy'],'b',linewidth=3.0) 
  17.     plt.legend(['Training Accuracy''Validation Accuracy'],fontsize=18) 
  18.     plt.xlabel('Epochs ',fontsize=16) 
  19.     plt.ylabel('Accuracy',fontsize=16) 
  20.     plt.title('Accuracy Curves',fontsize=16)  
  21.  
  22. plot_loss_accuracy(history) 

 

「加载具有最佳验证损失的模型」

  1. # 加载具有最佳验证损失的模型 
  2. model.load_weights('weights.hdf5'
  3. metrics = model.evaluate(testing_letters_images_scaled, testing_letters_labels_encoded, verbose=1) 
  4. print("Test Accuracy: {}".format(metrics[1])) 
  5. print("Test Loss: {}".format(metrics[0])) 

输出如下:

  1. 3360/3360 [==============================] - 0s 87us/step 
  2. Test Accuracy: 0.9678571224212646 
  3. Test Loss: 0.11759862171020359 

打印混淆矩阵。

  1. from sklearn.metrics import classification_report 
  2.  
  3. def get_predicted_classes(model, data, labels=None): 
  4.     image_predictions = model.predict(data) 
  5.     predicted_classes = np.argmax(image_predictions, axis=1) 
  6.     true_classes = np.argmax(labels, axis=1) 
  7.     return predicted_classes, true_classes, image_predictions 
  8.  
  9. def get_classification_report(y_true, y_pred): 
  10.     print(classification_report(y_true, y_pred)) 
  11.  
  12.  
  13. y_pred, y_true, image_predictions = get_predicted_classes(model, testing_letters_images_scaled, testing_letters_labels_encoded) 
  14. get_classification_report(y_true, y_pred) 

输出如下:

  1.           precision    recall  f1-score   support 
  2.  
  3.         0       1.00      0.98      0.99       120 
  4.         1       1.00      0.98      0.99       120 
  5.         2       0.80      0.98      0.88       120 
  6.         3       0.98      0.88      0.93       120 
  7.         4       0.99      0.97      0.98       120 
  8.         5       0.92      0.99      0.96       120 
  9.         6       0.94      0.97      0.95       120 
  10.         7       0.94      0.95      0.95       120 
  11.         8       0.96      0.88      0.92       120 
  12.         9       0.90      1.00      0.94       120 
  13.        10       0.94      0.90      0.92       120 
  14.        11       0.98      1.00      0.99       120 
  15.        12       0.99      0.98      0.99       120 
  16.        13       0.96      0.97      0.97       120 
  17.        14       1.00      0.93      0.97       120 
  18.        15       0.94      0.99      0.97       120 
  19.        16       1.00      0.93      0.96       120 
  20.        17       0.97      0.97      0.97       120 
  21.        18       1.00      0.93      0.96       120 
  22.        19       0.92      0.95      0.93       120 
  23.        20       0.97      0.93      0.94       120 
  24.        21       0.99      0.96      0.97       120 
  25.        22       0.99      0.98      0.99       120 
  26.        23       0.98      0.99      0.99       120 
  27.        24       0.95      0.88      0.91       120 
  28.        25       0.94      0.98      0.96       120 
  29.        26       0.95      0.97      0.96       120 
  30.        27       0.98      0.99      0.99       120 
  31.  
  32.  accuracy                           0.96      3360 
  33. macro avg       0.96      0.96      0.96      3360 
  34. ghted avg       0.96      0.96      0.96      3360 

最后绘制随机几个相关预测的图片

  1. indices = np.random.randint(0, testing_letters_labels.shape[0], size=49) 
  2. y_pred = np.argmax(model.predict(training_letters_images_scaled), axis=1) 
  3.  
  4. for i, idx in enumerate(indices): 
  5.     plt.subplot(7,7,i+1) 
  6.          
  7.     image_array = training_letters_images_scaled[idx][:,:,0] 
  8.     image_array = np.flip(image_array, 0) 
  9.     image_array = rotate(image_array, -90) 
  10.         
  11.     plt.imshow(image_array, cmap='gray'
  12.     plt.title("Pred: {} - Label: {}".format(y_pred[idx], (training_letters_labels[idx] -1))) 
  13.     plt.xticks([]) 
  14.     plt.yticks([]) 
  15. plt.show() 

 

来源:Python之王内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯