#include #import @class三者究竟该用哪个

本文详细介绍了Objective-C中三种引用头文件的方式:#include、#import与@class的区别与使用场景。通过对比分析,帮助开发者理解不同情况下的最优选择。

在OC中,引用文件可以通过#include、#import、@class三种方式,本文将讲解这三种方式的不同之处以及选择方式。

一. #include

1. 在C语言中,我们使用#include来引入头文件。使用#include “xx.h”来引入自定义的头文件,使用#include<xx.h>来引入库中的头文件。

2. 但是#include并不能防止重复引用头文件,如果在文件中,重复引用头文件,将会报错。(如:A引入了B,B引入了C,A再引入C,就会报错)

所以在OC中,几乎没有使用#incldue引头的情况。

二. #import

1. #import是#include的升级版,可以防止重复引入头文件这种现象的发生。

2. #import在引入头的时候,就是完全将头文件拷贝到现在的文件中。所以也有效率上的问题。

3. #import最大的问题在于,需要避免出现头文件递归引入的现象。(如:A引入B,B引入A,那么A、B的头文件会互相不停的拷贝)

三. @class

1. @class用来告诉编译器,有这样一个类,使书写代码时,不报错。

2. 因为#import引入头文件有效率问题,所以,当还没有调用类中方法,仅仅是定义类变量的时候,使用@class来提醒编译器。而在真正需要调用类方法的时候,进行#import。

(如:

现在需要在Student.h文件中定义一个Book类的变量book

那么不需要在Student.h中#import “Book.h”

而是在Student.h中@class Book 来是编译器不报错,告诉编译器我现在使用的Book是一个类,可以定义变量book

在之后的Student.m文件中,需要调用book方法时,在#import “Book.h”

从而降低#import在效率上的问题。)

3. 如果A是B的父类,那么这是在B.h中就必须要使用#import来引入A的头,因为需要知道A类中有哪些变量和方法,以免B类中重复定义。



# -*- coding: utf-8 -*- # @Time : 2021/6/17 20:29 # @Author : dejahu # @Email : 1148392984@qq.com # @File : train_mobilenet.py # @Software: PyCharm # @Brief : mobilenet模型训练代码,训练的模型会保存在models目录下,折线图会保存在results目录下 import tensorflow as tf import matplotlib.pyplot as plt from time import * # 数据集载函数,指明数据集的位置并统一处理为imgheight*imgwidth的大小,同时设置batch def data_load(data_dir, test_data_dir, img_height, img_width, batch_size): # 载训练集 train_ds = tf.keras.preprocessing.image_dataset_from_directory( data_dir, label_mode=&#39;categorical&#39;, seed=123, image_size=(img_height, img_width), batch_size=batch_size) # 载测试集 val_ds = tf.keras.preprocessing.image_dataset_from_directory( test_data_dir, label_mode=&#39;categorical&#39;, seed=123, image_size=(img_height, img_width), batch_size=batch_size) class_names = train_ds.class_names # 返回处理之后的训练集、验证集类名 return train_ds, val_ds, class_names # 构建mobilenet模型 # 模型载,指定图片处理的大小是否进行迁移学习 def model_load(IMG_SHAPE=(224, 224, 3), class_num=12): # 微调的过程中不需要进行归一化的处理 # 载预训练的mobilenet模型 base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE, include_top=False, weights=&#39;imagenet&#39;) # 将模型的主干参数进行冻结 base_model.trainable = False model = tf.keras.models.Sequential([ # 进行归一化的处理 tf.keras.layers.experimental.preprocessing.Rescaling(1. / 127.5, offset=-1, input_shape=IMG_SHAPE), # 设置主干模型 base_model, # 对主干模型的输出进行全局平均池化 tf.keras.layers.GlobalAveragePooling2D(), # 通过全连接层映射到最后的分类数目上 tf.keras.layers.Dense(class_num, activation=&#39;softmax&#39;) ]) model.summary() # 模型训练的优化器为adam优化器,模型的损失函数为交叉熵损失函数 model.compile(optimizer=&#39;adam&#39;, loss=&#39;categorical_crossentropy&#39;, metrics=[&#39;accuracy&#39;]) return model # 展示训练过程的曲线 def show_loss_acc(history): # 从h
03-21
<think>嗯,用户的问题是关于如何使用TensorFlow Keras中的MobileNetV2来训练自定义分类模型,特别是数据预处理的部分。首先,我需要回忆一下MobileNetV2的结构特点,记得它是轻量级的卷积神经网络,适合移动端嵌入式设备。用户提到的是自定义数据集,所以数据预处理是关键步骤。 首先,数据载部分,用户可能需要将图像数据从文件夹中读取,并分成训练集验证集。通常,TensorFlow的ImageDataGenerator或者使用tf.data.Dataset来处理。不过,Keras的ImageDataGenerator已经被弃用了,所以应该推荐使用tf.keras.utils.image_dataset_from_directory方法,直接从目录创建数据集。这样可以直接从文件夹结构生成带标签的数据集,比如每个类别的图片放在不同的子文件夹里。 接下来是数据预处理。MobileNetV2的输入需要特定的预处理,比如缩放像素值到[-1, 1]或者[0, 1]之间。记得MobileNetV2的预处理函数是tf.keras.applications.mobilenet_v2.preprocess_input,这个函数会自动处理输入的图像,比如归一化到[-1, 1]。同时,用户可能需要做数据增强,比如旋转、翻转、缩放等,以提高模型的泛化能力。数据增强可以通过tf.keras.Sequential层来添,比如RandomFlip、RandomRotation等,或者在ImageDataGenerator中进行,但后者可能已经被取代。 然后是模型构建部分。用户需要使用迁移学习,也就是载预训练的MobileNetV2模型,去掉顶部的全连接层,然后添自定义的分类层。需要冻结基模型的层,只训练顶部的层。或者根据数据集的大小决定冻结多少层。如果自定义数据集比较小,可能需要冻结大部分层,只训练顶层;如果数据量大,可以解冻更多层进行微调。 数据集的划分也是一个重点。用户需要将数据分为训练集验证集,可能还需要测试集。引用中提到使用train_test_split方法,但使用tf.data的话,可能需要用splitfolders库来处理,或者直接在载时指定subset为&#39;training&#39;&#39;validation&#39;。此外,还要注意数据集的平衡,确保每个类别的样本数量大致相当,避免类别不平衡的问题。 评估部分,用户可能需要在训练过程中监控验证集的准确率损失,使用回调函数如ModelCheckpoint或EarlyStopping。训练完成后,使用evaluate方法在测试集上评估模型性能。 可能用户还会遇到批量大小、学习率调整、优化器选择等问题。比如使用Adam优化器,设置合适的学习率,以及在训练过程中解冻部分层进行微调时,降低学习率以避免破坏预训练的权重。 另外,数据预处理中的图像尺寸需要调整到MobileNetV2的默认输入大小,通常是224x224像素。如果用户的数据集图片尺寸不一,需要在载时进行resize,或者在预处理步骤中使用tf.image.resize。 最后,生成相关问题的时候,需要考虑用户可能的后续问题,比如如何调整模型结构、优化训练速度、处理过拟合、部署模型等。这些都是用户在完成数据预处理后可能遇到的下一步问题。 需要确保回答中正确引用提供的参考资料,比如引用[3]关于数据切分,引用[4]关于迁移学习的部分。同时,代码示例要准确,比如使用image_dataset_from_directory,添数据增强层,构建模型,编译训练步骤。确保LaTeX格式正确,变量用$符号包裹,独立公式用$$,但在这个问题中可能涉及的数学公式不多,不过如果有的话需要注意格式。</think>### TensorFlow Keras MobileNetV2 自定义分类模型训练指南 #### 一、数据载与预处理 1. **数据集组织** - 按类别建立子目录结构: ``` dataset/ ├── class1/ ├── class2/ └── .../ ``` 2. **数据载** 使用`tf.keras.utils.image_dataset_from_directory`创建带标签数据集: ```python batch_size = 32 img_size = (224, 224) train_ds = tf.keras.utils.image_dataset_from_directory( &#39;dataset&#39;, validation_split=0.2, subset="training", seed=42, image_size=img_size, batch_size=batch_size ) val_ds = tf.keras.utils.image_dataset_from_directory( &#39;dataset&#39;, validation_split=0.2, subset="validation", seed=42, image_size=img_size, batch_size=batch_size ) ``` (数据集自动按4:1比例切分训练集验证集[^3]) 3. **数据增强** ```python data_augmentation = tf.keras.Sequential([ tf.keras.layers.RandomFlip("horizontal"), tf.keras.layers.RandomRotation(0.2), tf.keras.layers.RandomZoom(0.1) ]) ``` 4. **预处理** ```python preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input train_ds = train_ds.map(lambda x, y: (data_augmentation(x), y)) train_ds = train_ds.map(lambda x, y: (preprocess_input(x), y)) val_ds = val_ds.map(lambda x, y: (preprocess_input(x), y)) ``` #### 二、模型构建 1. **载基础模型** ```python base_model = tf.keras.applications.MobileNetV2( input_shape=(224, 224, 3), include_top=False, weights=&#39;imagenet&#39; ) base_model.trainable = False # 冻结基础模型 ``` 2. **构建分类头** ```python global_avg = tf.keras.layers.GlobalAveragePooling2D() dense = tf.keras.layers.Dense(128, activation=&#39;relu&#39;) prediction = tf.keras.layers.Dense(num_classes, activation=&#39;softmax&#39;) model = tf.keras.Sequential([ base_model, global_avg, dense, prediction ]) ``` #### 三、模型训练 ```python model.compile( optimizer=&#39;adam&#39;, loss=&#39;sparse_categorical_crossentropy&#39;, metrics=[&#39;accuracy&#39;] ) history = model.fit( train_ds, validation_data=val_ds, epochs=10 ) ``` (训练过程监控验证集准确率[^1]) #### 四、模型微调(可选) ```python base_model.trainable = True # 解冻最后10层 for layer in base_model.layers[:-10]: layer.trainable = False model.compile( optimizer=tf.keras.optimizers.Adam(1e-5), # 降低学习率 loss=&#39;sparse_categorical_crossentropy&#39;, metrics=[&#39;accuracy&#39;] ) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值