VGG16-keras 优化

article/2025/8/30 5:19:42

VGG16-keras 优化

  • 优化结果对比
  • VGG16网络结构
  • VGG16网络结构优化
  • 自定义loss
  • 训练
  • 预测

优化结果对比

原始VGG16
在这里插入图片描述
普通调优
在这里插入图片描述
使用预训练权重
在这里插入图片描述

VGG16网络结构

在这里插入图片描述

VGG16网络结构优化

1.增加正则化
2.使用BN/GN层(中间层数据的标准化)
3.使用dropout

Net.py

import keras
from keras.models import Sequential
from keras.utils import get_file
from keras.layers import Dense, Conv2D, MaxPool2D , Flatten,BatchNormalization,Dropout
import numpy as np# 原始VGG16
def VGG16(num_classes = 2,input_shape = (224, 224, 3)):# 使用序贯式模型model = Sequential()# 两个3*3*64卷积核 + 一个最大池化层model.add(Conv2D(input_shape=input_shape,filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 两个3*3*128卷积核 + 一个最大池化层model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*56卷积核 + 一个最大池化层model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。# 连接三个全连接层Dense,最后一层用于预测分类。model.add(Flatten())model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=4096,activation="relu"))model.add(Dense(units=num_classes, activation="softmax"))# 打印模型结构model.summary()return model#优化VGG16
def OVGG16(num_classes = 2,input_shape = (224, 224, 3)):weight_decay = 0.0005# 使用序贯式模型model = Sequential()# 两个3*3*64卷积核 + 一个最大池化层# 优化 增加L2正则化model.add(Conv2D(input_shape=input_shape,filters=64,kernel_size=(3,3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.3))model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same",  kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 两个3*3*128卷积核 + 一个最大池化层model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*56卷积核 + 一个最大池化层model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same",  kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same",  kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", kernel_regularizer=keras.regularizers.l2(weight_decay), activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same",  kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(Dropout(0.4))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same",  kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu"))# 优化 添加BN层和Dropoutmodel.add(BatchNormalization())model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))model.add(Dropout(0.5))# Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。# 连接三个全连接层Dense,最后一层用于预测分类。model.add(Flatten())model.add(Dense(units=512, kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu")) # VGG16为4096model.add(BatchNormalization())model.add(Dense(units=512, kernel_regularizer=keras.regularizers.l2(weight_decay),activation="relu")) # VGG16为4096model.add(BatchNormalization())model.add(Dropout(0.5))model.add(Dense(units=num_classes, activation="softmax")) # VGG16为1000# 打印模型结构model.summary()return model#迁移训练VGG16
def MVGG16(num_classes = 2,input_shape = (224, 224, 3)):#预训练模型WEIGHTS_PATH_NO_TOP = ('https://github.com/fchollet/deep-learning-models/''releases/download/v0.1/''vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5')# 使用序贯式模型model = Sequential()# 两个3*3*64卷积核 + 一个最大池化层model.add(Conv2D(input_shape=input_shape,filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(Conv2D(filters=64,kernel_size=(3,3),padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 两个3*3*128卷积核 + 一个最大池化层model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=128, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*56卷积核 + 一个最大池化层model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=256, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 三个3*3*512卷积核 + 一个最大池化层model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(Conv2D(filters=512, kernel_size=(3,3), padding="same", activation="relu"))model.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))# 加载预训练模型weights_path = get_file('vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5',WEIGHTS_PATH_NO_TOP,cache_subdir='models',file_hash='6d6bbae143d832006294945121d1f1fc')# 加载模型参数model.load_weights(weights_path)# 冻结前13层网络参数  保证加载的预训练参数不被改变for layer in model.layers[:13]:layer.trainable = False# Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。# 连接三个全连接层Dense,最后一层用于预测分类。model.add(Flatten())model.add(Dense(units=256,activation="relu")) # VGG16为4096model.add(Dense(units=128,activation="relu")) # VGG16为4096model.add(Dense(units=num_classes, activation="softmax")) # VGG16为1000# 打印模型结构model.summary()return model

自定义loss

Loss.py

import keras.backend as K
import tensorflow as tf# focal loss
def binary_focal_loss(gamma=2, alpha=0.25):"""Binary form of focal loss.适用于二分类问题的focal lossfocal_loss(p_t) = -alpha_t * (1 - p_t)**gamma * log(p_t)where p = sigmoid(x), p_t = p or 1 - p depending on if the label is 1 or 0, respectively.References:https://arxiv.org/pdf/1708.02002.pdfUsage:model.compile(loss=[binary_focal_loss(alpha=.25, gamma=2)], metrics=["accuracy"], optimizer=adam)"""alpha = tf.constant(alpha, dtype=tf.float32)gamma = tf.constant(gamma, dtype=tf.float32)def binary_focal_loss_fixed(y_true, y_pred):"""y_true shape need be (None,1)y_pred need be compute after sigmoid"""y_true = tf.cast(y_true, tf.float32)alpha_t = y_true*alpha + (K.ones_like(y_true)-y_true)*(1-alpha)p_t = y_true*y_pred + (K.ones_like(y_true)-y_true)*(K.ones_like(y_true)-y_pred) + K.epsilon()focal_loss = - alpha_t * K.pow((K.ones_like(y_true)-p_t),gamma) * K.log(p_t)return K.mean(focal_loss)return binary_focal_loss_fixeddef multi_category_focal_loss2(gamma=2., alpha=.25):"""focal loss for multi category of multi label problem适用于多分类或多标签问题的focal lossalpha控制真值y_true为1/0时的权重1的权重为alpha, 0的权重为1-alpha当你的模型欠拟合,学习存在困难时,可以尝试适用本函数作为loss当模型过于激进(无论何时总是倾向于预测出1),尝试将alpha调小当模型过于惰性(无论何时总是倾向于预测出0,或是某一个固定的常数,说明没有学到有效特征)尝试将alpha调大,鼓励模型进行预测出1。Usage:model.compile(loss=[multi_category_focal_loss2(alpha=0.25, gamma=2)], metrics=["accuracy"], optimizer=adam)"""epsilon = 1.e-7gamma = float(gamma)alpha = tf.constant(alpha, dtype=tf.float32)def multi_category_focal_loss2_fixed(y_true, y_pred):y_true = tf.cast(y_true, tf.float32)y_pred = tf.clip_by_value(y_pred, epsilon, 1. - epsilon)alpha_t = y_true*alpha + (tf.ones_like(y_true)-y_true)*(1-alpha)y_t = tf.multiply(y_true, y_pred) + tf.multiply(1-y_true, 1-y_pred)ce = -tf.log(y_t)weight = tf.pow(tf.subtract(1., y_t), gamma)fl = tf.multiply(tf.multiply(weight, ce), alpha_t)loss = tf.reduce_mean(fl)return lossreturn multi_category_focal_loss2_fixed

训练

import os
from keras.callbacks import ModelCheckpoint,EarlyStopping
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
import matplotlib.pyplot as plt
from Net import VGG16,OVGG16,MVGG16
from Loss import binary_focal_loss,multi_category_focal_loss2files_train = 0
files_validation = 0cwd = os.getcwd()
folder = 'train_data/train'
for sub_folder in os.listdir(folder):path, dirs, files = next(os.walk(os.path.join(folder,sub_folder)))files_train += len(files)folder = 'train_data/test'
for sub_folder in os.listdir(folder):path, dirs, files = next(os.walk(os.path.join(folder,sub_folder)))files_validation += len(files)print(files_train,files_validation)img_width, img_height = 48, 48
train_data_dir = "train_data/train"
validation_data_dir = "train_data/test"
nb_train_samples = files_train
nb_validation_samples = files_validation
batch_size = 32
epochs = 1000
num_classes = 2type = 1
# 加载原始VGG16
if type==0:model_name="ori.h5"img_name = "ori_epoch_loss.png"model = VGG16(num_classes=2, input_shape = (img_width, img_height, 3))
# 加载调优VGG16
elif type==1:model_name="opt.h5"img_name = "opt_epoch_loss.png"model = OVGG16(num_classes=2, input_shape = (img_width, img_height, 3))
# 加载迁移学习VGG16
elif type==2:model_name="Mopt.h5"img_name = "Mopt_epoch_loss.png"model = MVGG16(num_classes=2, input_shape = (img_width, img_height, 3))# 定义模型优化器, 使用分类交叉熵损失
# 随机梯度下降 lr是学习率 decay衰变参数 momentum和NAG 都是在更新梯度时顺应 loss function 的梯度来调整速度,并且对 SGD 进行加速。
opt = optimizers.SGD(lr=0.001, decay=1e-6, momentum=0.9,nesterov=True)
# focal loss
model.compile(loss = [binary_focal_loss(alpha=.5, gamma=1)], optimizer = opt, metrics=["accuracy"]) 
# 自带loss
# mean_squared_error
# mean_absolute_error
# mean_absolute_percentage_error
# mean_squared_logarithmic_error
# hinge
# logcosh
# squared_hinge
# categorical_crossentropy
# sparse_categorical_crossentropy
# binary_crossentropy
# kullback_leibler_divergence
# poisson
# cosine_proximity
# model.compile(loss = "categorical_crossentropy", optimizer = opt, metrics=["accuracy"]) train_datagen = ImageDataGenerator(
rescale = 1./255,
horizontal_flip = True,
fill_mode = "nearest",
zoom_range = 0.1,
width_shift_range = 0.1,
height_shift_range=0.1,
rotation_range=5)test_datagen = ImageDataGenerator(
rescale = 1./255,
horizontal_flip = True,
fill_mode = "nearest",
zoom_range = 0.1,
width_shift_range = 0.1,
height_shift_range=0.1,
rotation_range=5)train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_height, img_width),
batch_size = batch_size,
class_mode = "categorical")validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size = (img_height, img_width),
class_mode = "categorical")# 定义模型和精度计算方式
checkpoint = ModelCheckpoint(model_name, monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)
early = EarlyStopping(monitor='val_acc', min_delta=0, patience=100, verbose=1, mode='auto')# 训练模型并计算精度
history = model.fit_generator(
train_generator,
samples_per_epoch = nb_train_samples,
epochs = epochs,
validation_data = validation_generator,
nb_val_samples = nb_validation_samples,
callbacks = [checkpoint, early])plt.plot(history.history["acc"])
plt.plot(history.history['val_acc'])
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title("model accuracy")
plt.ylabel("Accuracy")
plt.xlabel("Epoch")
plt.legend(["Accuracy","Validation Accuracy","loss","Validation Loss"])
plt.savefig(img_name)
plt.show()

预测

import cv2
from keras.models import load_model
from Loss import binary_focal_loss,multi_category_focal_loss2type = 1
# 加载原始VGG16
if type ==0:weights_path="ori.h5"
# 加载调优VGG16
elif type==1:weights_path="opt.h5"
# 加载迁移学习VGG16
elif type==2:weights_path="Mopt.h5"image = cv2.imread(path)
class_dictionary = {}
class_dictionary[0] = 'empty'
class_dictionary[1] = 'occupied'model=load_model(weights_path,custom_objects={'binary_focal_loss_fixed':binary_focal_loss(alpha=.5, gamma=1)})
#预处理
img = image/255.
#转换成4D tensor
image = np.expand_dims(img, axis=0)
# 用训练好的模型进行训练
class_predicted = model.predict(image)
inID = np.argmax(class_predicted[0])
label = class_dictionary[inID]
if label == 'empty':print(0)
else:print(1)

http://chatgpt.dhexx.cn/article/f7YN3f7x.shtml

相关文章

VGG16论文解读

VGGNET VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)。对于给定的感受野(与输出有关的输入图片的局部大小),采用堆积的小卷积核是优于采用…

VGG16模型详解 and 代码搭建

目录 一. VGG 网络模型 二. 代码复现 1. 网络搭建 2.数据集制作(pkl) 3.源码地址 一. VGG 网络模型 Alexnet是卷积神经网络的开山之作,但是由于卷积核太大,移动步长大,无填充,所以14年提出的VGG网络解决了这一问题。而且VGG网…

动手学习VGG16

VGG 论文 《Very Deep Convolutional Networks for Large-Scale Image Recognition》 论文地址:https://arxiv.org/abs/1409.1556 使用重复元素的网络(VGG) 以学习VGG的收获、VGG16的复现二大部分,简述VGG16网络。 一. 学习VGG的收获 VGG网络明确指…

VGG16

VGG16模型的学习以及源码分析 part one 主要学习参考 pytorch 英文文档VGG16学习笔记VGG16网络原理分析与pytorch实现【深度学习】全面理解VGG16模型VGG模型的pytorch代码实现VGG16源代码详解【论文】 VERY DEEP CONVOLUTIONAL NETWORKS FOR LARGE-SCALE IMAGE RECOGNITION p…

VGG16 - 用于分类和检测的卷积网络

VGG16是由牛津大学的K. Simonyan和A. Zisserman在“用于大规模图像识别的非常深卷积网络”的论文中提出的卷积神经网络模型。 该模型在ImageNet中实现了92.7%的前5个测试精度,这是属于1000个类的超过1400万张图像的数据集。它是ILSVRC-2014提交的着名模型…

VGG-16网络结构详解

VGG,又叫VGG-16,顾名思义就是有16层,包括13个卷积层和3个全连接层,是由Visual Geometry Group组的Simonyan和Zisserman在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型&…

经典卷积神经网络——VGG16

VGG16 前言一、VGG发展历程二、VGG网络模型三、VGG16代码详解1.VGG网络架构2.VGG16网络验证2.读取数据,进行数据增强3.训练模型,测试准确率 四、VGG缺点 前言 我们都知道Alexnet是卷积神经网络的开山之作,但是由于卷积核太大,移动…

VGG16网络模型的原理与实现

VGG 最大的特点就是通过比较彻底地采用 3x3 尺寸的卷积核来堆叠神经网络,这样也加深整个神经网络的深度。这两个重要的改变对于人们重新定义卷积神经网络模型架构也有不小的帮助,至少证明使用更小的卷积核并且增加卷积神经网络的深度,可以更有…

深度学习——VGG16模型详解

1、网络结构 VGG16模型很好的适用于分类和定位任务,其名称来自牛津大学几何组(Visual Geometry Group)的缩写。 根据卷积核的大小核卷积层数,VGG共有6种配置,分别为A、A-LRN、B、C、D、E,其中D和E两种是最…

RK3399平台开发系列讲解(PCI/PCI-E)5.54、PCIE INTx中断机制

文章目录 一、PCIe中断过程二、PCIE 控制器支持的中断三、PCIE 控制器注册中断四、PCIe设备中断号分配沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇章将介绍RK3399平台PCIE总线中断INTx相关内容。 一、PCIe中断过程 层级结构为:PCIe设备 => PCIe控制器 =&g…

RK3399—中断

中断是操作系统最常见的事件之一,无论是系统层的“软中断”还是CPU底层的“硬中断”都是编程时常用的。中断的作用之一是充分利用CPU资源,正常情况下,CPU执行用户任务,当外设触发中断产生时,CPU停止当前任务&#xff0…

基于RK3399分析Linux系统下的CPU时钟管理 - 第3篇

1. 时钟系统结构 rockchip的时钟系统代码位于drivers/clk/rockchip,目录整体结构如下: ├── rockchip │ ├── clk.c---------------时钟系统注册 │ ├── clk-cpu.c-----------CPU调频 │ ├── clk-ddr.c-----------DDR调频 │ ├──…

基于RK3399+PID的手持稳定云台的设计与实现

手持稳定云台的主要作用是将外界环境因数引起的相机姿态变化进行隔离。如因操作者运动造成的机体震动、风阻力矩等,为了确保工作中相机的视轴始终保持期望的姿态不动。云台相机要拍摄出高质量的影像最重要的就是保证相机的视轴相对目标保持稳定。因此在相机拍摄的过…

RK3399学习

RK3399学习 韦东山rk3399:http://dev.t-firefly.com/forum-460-1.html firefly官网教程:http://wiki.t-firefly.com/zh_CN/Firefly-RK3399/started.html firefly官网3399资料:http://dev.t-firefly.com/forum-263-1.html 100ask 3399-pc教…

RK3399平台开发系列讲解(内核入门篇)1.53、platform平台设备

🚀返回专栏总目录 文章目录 一、设备配置-非设备树1.1、资源1.2、平台数据1.3、声明平台设备二、设备配置 - DTS沉淀、分享、成长,让自己和他人都能有所收获!😄 📢平台设备在内核中表示为struct platform_device的实例。 有两种方法可以把有关设备所需的资源(IRQ、DMA…

RK3399 Android7.1 编译

RK3399 Android7.1 编译 文章目录 RK3399 Android7.1 编译前言设置 Linux 编译环境安装 JDK可选- 更新默认的 Java 版本 安装所需的程序包(Ubuntu 14.04) 下载 Android SDK 前言 RK官网编译 Android搭建编译环境 设置 Linux 编译环境 使用的环境Linux 16.0.4 安装 JDK 如…

基于RK3399+5G的医用视频终端设计

当前在各种先进的信息通信技术的驱动下,医疗行业已呈现出信息化、移动化、智能化的发展趋势。特别是 5G 通信技术的落地应用推动了智慧医疗行业的 蓬勃发展,涌现出大量基于 5G 技术的医疗健康应用与服务,进一步融合了 5G 、 物联网与大数据…

RK3399平台开发系列讲解(PCI/PCI-E)PCIE相关配置说明

🚀返回专栏总目录 文章目录 一、DTS 配置二、menuconfig 配置三、cmdline 配置沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍在使用 RK3399 平台 PCIE 时候的配置。 一、DTS 配置 ep-gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>; 此项是设置 PCIe…

RK3399快速上手 | 02-rockchip rk3399 linux sdk的使用(编译内核、编译uboot)

更新时间更新内容2022-09-15增加内核编译方法2022-10-21增加uboot编译方法和sdk开发版配置链路分析一、sdk区别 瑞芯微提供了两套sdk,一套是通过官方git仓库释放,适合于项目使用,另一套是通过github释放,适合于爱好者。 本文中使用从瑞芯微官方释放的正式linux sdk 2.7版…

RK3399平台开发系列讲解(中断篇)中断控制器驱动初始化

🚀返回专栏总目录 文章目录 一、设备树源文件1.1、gic控制器节点1.2、timer节点二、中断控制器匹配表三、中断控制器初始化3.1、函数of_irq_init3.2、函数gicv3_of_init3.3、函数gic_init_bases沉淀、分享、成长,让自己和他人都能有所收获!😄 一、设备树源文件 ARM64架构…