神经网络搭建六步法扩展

神经网络搭建六步法扩展

image-20220308151509935

1.自制数据集,应对特定应用

之前我们使用“MNIST数据集”,可以直接导入使用“tf.keras.datasets.mnist.load_data()”,并非所有的数据都有制作玩呗可以直接导入的数据集,因此我么你需要学会自己制作数据集。

以“MNIST”中的数据为例,我们给出:

60000张训练图片、训练图片的“图片名字 数字”形式的txt文件、10000张测试数据、测试图片的“图片名字 数字”形式的txt文件

image-20220308152142846

image-20220308152212661

代码实现

训练数据和测试数据的制作步骤是一样的,因此我们可以写一个函数来处理。

def generateds(path, txt):
    ###
    ###
    return x, y_

对于制作流程,我们的思路是;

  1. 读取出txt文件中的内容(contents)
  2. 用x和y_两个list存放特征数据和标签
  3. 遍历每一行的内容
  4. 对每一行,根据图片名字和图片文件夹路径读入图片,转换成合适的数据结构,放入x中;将标签放入y_中
  5. 返回x, y_
def generateds(path, txt):
    f = open(txt, 'r')
    contents = f.readlines()
    f.close() # 记得关闭文件哦

    x, y_ = [], []
    for content in contents:
        value = content.split() # 以空格分开,图片路径为value[0] , 标签为value[1] , 存入列表
        img_path = path + value[0] # 图片完整路径
        img = Image.open(img_path) # 读入图片
        img = np.array(img.convert('L'))  # 图片变为8位宽灰度值的np.array格式
        img = img / 255.  # 归一化
        x.append(img)
        y_.append(value[1])
        print('loading : ' + content)

    x = np.array(x)  # 变为np.array格式
    y_ = np.array(y_)  # 变为np.array格式
    y_ = y_.astype(np.int64)  # 变为64位整型
    return x, y_  # 返回输入特征x,返回标签y_

我们可以把上面制作数据集的代码和“六步法”的代码何在一起,先检查是否存在数据集,如果存在直接load,如果不存在,先制作,然后把数据集存储到磁盘以备之后使用。(制作数据集非常耗时间)

import tensorflow as tf
from PIL import Image
import numpy as np
import os

train_path = './mnist_image_label/mnist_train_jpg_60000/'
train_txt = './mnist_image_label/mnist_train_jpg_60000.txt'
x_train_savepath = './mnist_image_label/mnist_x_train.npy'
y_train_savepath = './mnist_image_label/mnist_y_train.npy'

test_path = './mnist_image_label/mnist_test_jpg_10000/'
test_txt = './mnist_image_label/mnist_test_jpg_10000.txt'
x_test_savepath = './mnist_image_label/mnist_x_test.npy'
y_test_savepath = './mnist_image_label/mnist_y_test.npy'


def generateds(path, txt):
    f = open(txt, 'r')
    contents = f.readlines()
    f.close()
    x, y_ = [], [
    for content in contents:
        value = content.split(
        img_path = path + value[0]
        img = Image.open(img_path)
        img = np.array(img.convert('L'))
        img = img / 255.  
        x.append(img) 
        y_.append(value[1]) 
        print('loading : ' + content) 

    x = np.array(x) 
    y_ = np.array(y_) 
    y_ = y_.astype(np.int64) 
    return x, y_  # 返回输入特征x,返回标签y_

# 如果数据集存在就直接使用,如果不存在就 先生成 再存储
if os.path.exists(x_train_savepath) and os.path.exists(y_train_savepath) and os.path.exists(
        x_test_savepath) and os.path.exists(y_test_savepath):
    print('-------------Load Datasets-----------------')
    x_train_save = np.load(x_train_savepath)
    y_train = np.load(y_train_savepath)
    x_test_save = np.load(x_test_savepath)
    y_test = np.load(y_test_savepath)
    x_train = np.reshape(x_train_save, (len(x_train_save), 28, 28))
    x_test = np.reshape(x_test_save, (len(x_test_save), 28, 28))
else:
    print('-------------Generate Datasets-----------------')
    x_train, y_train = generateds(train_path, train_txt)
    x_test, y_test = generateds(test_path, test_txt)

    print('-------------Save Datasets-----------------')
    x_train_save = np.reshape(x_train, (len(x_train), -1))
    x_test_save = np.reshape(x_test, (len(x_test), -1))
    np.save(x_train_savepath, x_train_save)
    np.save(y_train_savepath, y_train)
    np.save(x_test_savepath, x_test_save)
    np.save(y_test_savepath, y_test)

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1)

model.summary()

2.数据增强,增大数据量

有些时候,我们的数据量太小,需要使用数据增强来丰富我们的数据集,数据增强就是把原有的数据做一些变化(如图片的旋转,镜像等)来扩充数据。

步骤

image_gen_train=tf.keras.preprocessing.image.ImageDataGenerator( 增 强 方法)

image_gen_train.fit(x_train)

常用增强方法

  • 缩放系数:rescale=所有数据将乘以提供的值
  • 随机旋转:rotation_range=随机旋转角度数范围
  • 宽度偏移:width_shift_range=随机宽度偏移量
  • 高度偏移:height_shift_range=随机高度偏移量
  • 水平翻转:horizontal_flip=是否水平随机翻转
  • 随机缩放:zoom_range=随机缩放的范围 [1-n,1+n]
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator

mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
# 1. !!!!!!!!!!!!!!!!!!
# 给数据增加一个维度,从(60000, 28, 28)reshape为(60000, 28, 28, 1)
x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)  



image_gen_train=ImageDataGenerator(
    rescale=1./1.,
    rotation_range=45,
    width_shift_range=.15,
    height_shift_range=.15,
    horizontal_flip=False,
    zoom_range=0.5
)
image_gen_train.fit(x_train)

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

# 2.!!!!!!!!!!!!!!!!!
model.fit(image_gen_train.flow(x_train,y_train,batch_size=32),epochs=5,validation_data=(x_test,y_test),validation_freq=1)

model.summary()

注意:

  1. 数据增强函数的输入要求是4维,需要通过reshape调整
  2. model.fit输入训练数据和batch时要是用“image_gen_train.flow(x_train,y_train,batch_size=)”

3.断点续训,存取模型

3.1读取模型

读取模型使用model.load_weights()

checkpoint_save_path = "./checkpoint/mnist.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

3.2保存模型

借助tensorflow给出的回调函数,直接保存参数和网络

具体用法如下:

#上接“六步法”中的前四部

checkpoint_save_path = "./checkpoint/mnist.ckpt"
# 如果模型已经被保存过 导入模型继续训练
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)

# 保存模型
cp_callback=tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                               save_weights_only=True,
                                               save_best_only=True)

history=model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), 				                   validation_freq=1,callbacks=[cp_callback])

#下面是“六步法”的最后一步

4.参数提取,写至文本

4.1提取可训练参数

model.trainable_variables返回模型中可训练的参数。

4.2设置 print 输出格式

如果数据量太大,print输出时默认会将中间的数据省略,用“省略号”表示。

np.set_printoptions(

precision=小数点后按四舍五入保留几位,

threshold=数组元素数量少于或等于门槛值,打印全部元素;否则打印门槛值+1 个元素,中间用省略号补充

)

把threshold设置为np.inf即可输出全部数据元素。

代码如下,需要关注的地方我用!标注:

import tensorflow as tf
import os
import numpy as np

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
np.set_printoptions(threshold=np.inf)


mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              metrics=['sparse_categorical_accuracy'])

checkpoint_save_path = "./checkpoint/mnist.ckpt"
if os.path.exists(checkpoint_save_path + '.index'):
    print('-------------load the model-----------------')
    model.load_weights(checkpoint_save_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,
                                                 save_weights_only=True,
                                                 save_best_only=True)
history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])

model.summary()

# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
print(model.trainable_variables)
file=open('./weights.txt','w')
for v in model.trainable_variables:
    file.write(str(v.name)+'\n')
    file.write(str(v.shape)+'\n')
    file.write(str(v.numpy())+'\n')
file.close()

weights.txt内容:

5.acc/loss 可视化,查看效果

使用变量history接收model.fit返回值,之后history.history获取acc/loss值。

history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,callbacks=[cp_callback])

acc=history.history['sparse_categorical_accuracy'] # 训练数据正确率
val_acc=history.history['val_sparse_categorical_accuracy']  # 测试数据正确率
loss=history.history['loss']  # 训练数据损失值
val_loss=history.history['val_loss']  # 测试数据损失值
# 画图
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

Figure_1

6、应用程序,给图识物

这里会给神经网络输入一条特征数据(手写数字图),让学习后的神经网络来预测这个数字是多少。

eg.

在这里插入图片描述

6.1前向传播执行应用

使用model.predict(输入数据, batch_size=整数),返回前向传播计算结果。

因为我们这里是使用已经训练好的模型,所以需要:

  1. 构建一样的网络结构
  2. 加载保存的模型
  3. model.predict(x_predict)进行预测
from PIL import Image
import numpy as np
import tensorflow as tf

# 模型保存地址
model_save_path = './checkpoint/mnist.ckpt'

# 1. 构建一样的网络结构
model = tf.keras.models.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')])

# 2.  加载保存的模型
model.load_weights(model_save_path)

preNum = int(input("input the number of test pictures:"))

for i in range(preNum):
    image_path = input("the path of test picture:")
    img = Image.open(image_path)
    # 预处理 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    # 变为28*28
    img = img.resize((28, 28), Image.ANTIALIAS)
    # 变为灰度图
    img_arr = np.array(img.convert('L'))

    # 变为黑底白字
    # 方法一
    #img_arr = 255-img_arr
    # 方法二
    for i in range(28):
        for j in range(28):
            if img_arr[i][j] < 200:
                img_arr[i][j] = 255
            else:
                img_arr[i][j] = 0

    # 归一化
    img_arr = img_arr / 255.0
    # 增加一个维度,变为1*28*28 为了和训练时使用的数据的维度一致
    x_predict = img_arr[tf.newaxis, ...]
    # 3.  预测
    result = model.predict(x_predict)
    # pred是预测认为是0-9各个数字的概率
    pred = tf.argmax(result, axis=1)

    print('\n')
    # pred是张量,需要用tf.print
    tf.print(pred)

这里需要注意,因为我们训练神经网络时使用的是28*28的灰度图,黑底白字,所以需要把我们这里需要预测的图片(上图)转换为“28*28的灰度图,黑底白字”格式。

其中,变为黑底白字可以使用简单的方法一:img_arr = 255 - img_arr

也可以使用复杂的方法二,方法二将所有像素转换为“纯黑0”或“纯白255”,这样做可以降低图片中的噪声带来的影响。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
无刷直流电机(BLDC)是一种高效、可靠且具有较长寿命的电机,适用于许多应用领域,如电动车、无人机、家用电器等。驱动无刷直流电机的步法是一种常见的驱动方式,下面是详细的步骤: 1. 确定相序:BLDC电机由三个相位组成,分别为A相、B相和C相。确定正确的相序非常重要,否则电机将无法正常运转。可以使用霍尔传感器或者反电势检测来确定相序。 2. 选择逆变器:逆变器是将直流电源转换为交流电源的设备。在BLDC电机驱动中,需要使用三相逆变器。逆变器的选择应根据电机的功率和应用需求来确定。 3. PWM信号生成:脉宽调制(PWM)信号用于控制逆变器输出的电流。通过调整PWM信号的占空比,可以控制电机的转速和扭矩。通常使用微控制器或专用的PWM控制芯片来生成PWM信号。 4. 控制算法:控制算法是决定电机如何运转的关键。最常用的算法是步法,也称为“正弦PWM”算法。该算法通过依次激活每个相位来驱动电机,以实现正常的旋转。具体步骤如下: - 步骤1:激活A相,关闭B相和C相; - 步骤2:激活A相和B相,关闭C相; - 步骤3:激活B相,关闭A相和C相; - 步骤4:激活B相和C相,关闭A相; - 步骤5:激活C相,关闭A相和B相; - 步骤6:激活C相和A相,关闭B相; 循环以上个步骤,就可以实现电机的旋转。 5. 相电流控制:为了保证电机的稳定运转,需要对每个相位的电流进行控制。通常使用电流传感器来测量电流,并通过调整PWM信号的占空比来控制电流大小。 6. 速度和位置反馈:为了实现更精确的控制,可以使用速度和位置传感器来反馈电机的转速和位置信息。根据反馈信息,可以动态调整PWM信号和电流控制策略,以实现所需的运动控制效果。 以上就是驱动无刷直流电机的步法。根据实际应用需求和控制算法的选择,可能会有一些细微的差异,但基本原理是相同的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值