热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

深度神经网络模型,从LeNet5到

欢迎关注博主的公众号:happyGirl的异想世界。有更多干货还有技术讨论群哦~LeNet-5LeNet-5是YannLeCun在1998年设计的用于手写数字识别

欢迎关注博主的公众号:happyGirl的异想世界。有更多干货还有技术讨论群哦~

LeNet-5

LeNet-5是Yann LeCun在1998年设计的用于手写数字识别的卷积神经网络,当年美国大多数银行就是用它来识别支票上面的手写数字的,它是早期卷积神经网络中最有代表性的实验系统之一。

LenNet-5共有7层(不包括输入层),每层都包含不同数量的训练参数,如下图所示。

其参数:

  • input:输入图片,32*32像素;
  • C1:5*5卷积核,生成6个feature maps,共需要(6*5*5 + 6)=156个参数;
  • S2:2*2个像素相加,然后乘以一个参数,加上一个偏置,共计2*6=12个参数;
  • C3:5*5卷积核,生成16个feature maps,每个feature map由S2中若干个feature maps卷积得到,如图Table1所示;
  • S4:和S2相同的操作,共计16*2 = 32个参数;
  • C5:与S4全连接,共计(5*5*16*120+120)=48120个参数;
  • F6:与C5全连接,共计(120*84+84) = 10164 个参数;
  • output: 与F6全连接。

AlexNet

AlexNet是2012年ImageNet竞赛冠军获得者Hinton和他的学生Alex Krizhevsky设计的。也是在那年之后,更多的更深的神经网络被提出,比如优秀的vgg,GoogLeNet。 这对于传统的机器学习分类算法而言,已经相当的出色。

alexNet为8层深度网络,其中5层卷积层和3层全连接层,不计LRN层和池化层。结构图如下图所示:

详解各层训练参数的计算:

前五层:卷积层

后三层:全连接层

整体计算图:

也可以这么看:

VGGNet

VGGNet (https://arxiv.org/pdf/1409.1556.pdf) 发布于2014年,作者是Karen Simonyan和Andrew Zisserman,该网络表明堆叠多个层是提升计算机视觉性能的关键因素。VGGNet包含16或19层,主要由小型的3X3卷积操作和2X2池化操作组成。

创新点:VGGNet全部使用3*3的卷积核和2*2的池化核,通过不断加深网络结构来提升性能。网络层数的增长并不会带来参数量上的爆炸,因为参数量主要集中在最后三个全连接层中。同时,两个3*3卷积层的串联相当于1个5*5的卷积层,3个3*3的卷积层串联相当于1个7*7的卷积层,即3个3*3卷积层的感受野大小相当于1个7*7的卷积层。但是3个3*3的卷积层参数量只有7*7的一半左右,同时前者可以有3个非线性操作,而后者只有1个非线性操作,这样使得前者对于特征的学习能力更强。

使用1*1的卷积层来增加线性变换,输出的通道数量上并没有发生改变。这里提一下1*1卷积层的其他用法,1*1的卷积层常被用来提炼特征,即多通道的特征组合在一起,凝练成较大通道或者较小通道的输出,而每张图片的大小不变。有时1*1的卷积神经网络还可以用来替代全连接层。

    其他小技巧。VGGNet在训练的时候先训级别A的简单网络,再复用A网络的权重来初始化后面的几个复杂模型,这样收敛速度更快。VGGNet作者总结出LRN层作用不大,越深的网络效果越好,1*1的卷积也是很有效的,但是没有3*3的卷积效果好,因为3*3的网络可以学习到更大的空间特征。

优点:1.参数量减少了 81%(相比alxexnet),而感受野保持不变。

2.小卷积核的使用也扮演了正则化器的角色,并提高了不同卷积核的有效性。

缺点:其评估的开销比浅层网络更加昂贵,内存和参数(140M)也更多。这些参数的大部分都可以归因于第一个全连接层。

 网络结构:VGGNet的网络结构如下图所示。VGGNet包含很多级别的网络,深度从11层到19层不等,比较常用的是VGGNet-16和VGGNet-19。VGGNet把网络分成了5段,每段都把多个3*3的卷积网络串联在一起,每段卷积后面接一个最大池化层,最后面是3个全连接层和一个softmax层。网络结构图:

代码实现参考自tensorflow的开源实现:

#%%
# Copyright 2016 The TensorFlow Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
from datetime import datetime
import math
import time
import tensorflow as tfdef conv_op(input_op, name, kh, kw, n_out, dh, dw, p):n_in = input_op.get_shape()[-1].valuewith tf.name_scope(name) as scope:kernel = tf.get_variable(scope+"w",shape=[kh, kw, n_in, n_out],dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer_conv2d())conv = tf.nn.conv2d(input_op, kernel, (1, dh, dw, 1), padding='SAME')bias_init_val = tf.constant(0.0, shape=[n_out], dtype=tf.float32)biases = tf.Variable(bias_init_val, trainable=True, name='b')z = tf.nn.bias_add(conv, biases)activation = tf.nn.relu(z, name=scope)p += [kernel, biases]return activationdef fc_op(input_op, name, n_out, p):n_in = input_op.get_shape()[-1].valuewith tf.name_scope(name) as scope:kernel = tf.get_variable(scope+"w",shape=[n_in, n_out],dtype=tf.float32, initializer=tf.contrib.layers.xavier_initializer())biases = tf.Variable(tf.constant(0.1, shape=[n_out], dtype=tf.float32), name='b')activation = tf.nn.relu_layer(input_op, kernel, biases, name=scope)p += [kernel, biases]return activationdef mpool_op(input_op, name, kh, kw, dh, dw):return tf.nn.max_pool(input_op,ksize=[1, kh, kw, 1],strides=[1, dh, dw, 1],padding='SAME',name=name)def inference_op(input_op, keep_prob):p = []# assume input_op shape is 224x224x3# block 1 -- outputs 112x112x64conv1_1 = conv_op(input_op, name="conv1_1", kh=3, kw=3, n_out=64, dh=1, dw=1, p=p)conv1_2 = conv_op(conv1_1, name="conv1_2", kh=3, kw=3, n_out=64, dh=1, dw=1, p=p)pool1 = mpool_op(conv1_2, name="pool1", kh=2, kw=2, dw=2, dh=2)# block 2 -- outputs 56x56x128conv2_1 = conv_op(pool1, name="conv2_1", kh=3, kw=3, n_out=128, dh=1, dw=1, p=p)conv2_2 = conv_op(conv2_1, name="conv2_2", kh=3, kw=3, n_out=128, dh=1, dw=1, p=p)pool2 = mpool_op(conv2_2, name="pool2", kh=2, kw=2, dh=2, dw=2)# # block 3 -- outputs 28x28x256conv3_1 = conv_op(pool2, name="conv3_1", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p)conv3_2 = conv_op(conv3_1, name="conv3_2", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p)conv3_3 = conv_op(conv3_2, name="conv3_3", kh=3, kw=3, n_out=256, dh=1, dw=1, p=p) pool3 = mpool_op(conv3_3, name="pool3", kh=2, kw=2, dh=2, dw=2)# block 4 -- outputs 14x14x512conv4_1 = conv_op(pool3, name="conv4_1", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)conv4_2 = conv_op(conv4_1, name="conv4_2", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)conv4_3 = conv_op(conv4_2, name="conv4_3", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)pool4 = mpool_op(conv4_3, name="pool4", kh=2, kw=2, dh=2, dw=2)# block 5 -- outputs 7x7x512conv5_1 = conv_op(pool4, name="conv5_1", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)conv5_2 = conv_op(conv5_1, name="conv5_2", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)conv5_3 = conv_op(conv5_2, name="conv5_3", kh=3, kw=3, n_out=512, dh=1, dw=1, p=p)pool5 = mpool_op(conv5_3, name="pool5", kh=2, kw=2, dw=2, dh=2)# flattenshp = pool5.get_shape()flattened_shape = shp[1].value * shp[2].value * shp[3].valueresh1 = tf.reshape(pool5, [-1, flattened_shape], name="resh1")# fully connectedfc6 = fc_op(resh1, name="fc6", n_out=4096, p=p)fc6_drop = tf.nn.dropout(fc6, keep_prob, name="fc6_drop")fc7 = fc_op(fc6_drop, name="fc7", n_out=4096, p=p)fc7_drop = tf.nn.dropout(fc7, keep_prob, name="fc7_drop")fc8 = fc_op(fc7_drop, name="fc8", n_out=1000, p=p)softmax = tf.nn.softmax(fc8)predictions = tf.argmax(softmax, 1)return predictions, softmax, fc8, pdef time_tensorflow_run(session, target, feed, info_string):num_steps_burn_in = 10total_duration = 0.0total_duration_squared = 0.0for i in range(num_batches + num_steps_burn_in):start_time = time.time()_ = session.run(target, feed_dict=feed)duration = time.time() - start_timeif i >= num_steps_burn_in:if not i % 10:print ('%s: step %d, duration = %.3f' %(datetime.now(), i - num_steps_burn_in, duration))total_duration += durationtotal_duration_squared += duration * durationmn = total_duration / num_batchesvr = total_duration_squared / num_batches - mn * mnsd = math.sqrt(vr)print ('%s: %s across %d steps, %.3f +/- %.3f sec / batch' %(datetime.now(), info_string, num_batches, mn, sd))def run_benchmark():with tf.Graph().as_default():image_size = 224images = tf.Variable(tf.random_normal([batch_size,image_size,image_size, 3],dtype=tf.float32,stddev=1e-1))keep_prob = tf.placeholder(tf.float32)predictions, softmax, fc8, p = inference_op(images, keep_prob)init = tf.global_variables_initializer()config = tf.ConfigProto()config.gpu_options.allocator_type = 'BFC'sess = tf.Session(config=config)sess.run(init)time_tensorflow_run(sess, predictions, {keep_prob:1.0}, "Forward")objective = tf.nn.l2_loss(fc8)grad = tf.gradients(objective, p)time_tensorflow_run(sess, grad, {keep_prob:0.5}, "Forward-backward")batch_size=32
num_batches=100
run_benchmark()

ResNet

何凯明2016CVPR:Deep Residual Learning for Image Recognition

代表网络 :resnet50 resnet101,resnet152

优点:

1.增加了神经网络架构的跳过连接(skip connection),卷积层的默认函数变成了恒等函数,卷积核学到的任何新信息都可以在基本表征中添加或减去,因此更容易优化残差映射。跳过连接不会增加参数的数量,但可以获得更稳定的训练和显著的性能提升。

2.每次卷积完成后、激活进行前都采取批归一化。

3.网络删除了全连接层,并使用平均池化层减少参数的数量。由于网络加深,卷积层的抽象能力更强,从而减少了对全连接层的需求。

4.引用1*1卷机来降维和升维,在进行3*3卷机之前,先对特征图进行降为,卷机后升维,恢复原来的维度。这样进行卷机操作的时候可以降低参数的数量,而且可以增加非线性。

 

具体:

 

Inception

(详见http://baijiahao.baidu.com/s?id=1601882944953788623&wfr=spider&for=pc)

代表网络 :

Inception v1,

Inception v2 和 Inception v3,

Inception v4 和 Inception-ResNet

Inception v1

论文:Going deeper with convolutions

论文链接:https://arxiv.org/pdf/1409.4842v1.pdf

Inception v2

论文:Rethinking the Inception Architecture for Computer Vision

论文地址:https://arxiv.org/pdf/1512.00567v3.pdf

Inception v3

这个非常常用

问题:

作者注意到辅助分类器直到训练过程快结束时才有较多贡献,那时准确率接近饱和。作者认为辅助分类器的功能是正则化,尤其是它们具备 BatchNorm 或 Dropout 操作时。是否能够改进 Inception v2 而无需大幅更改模块仍需要调查。

解决方案:

Inception Net v3 整合了前面 Inception v2 中提到的所有升级,还使用了:

RMSProp 优化器;Factorized 7x7 卷积;辅助分类器使用了 BatchNorm;标签平滑(添加到损失公式的一种正则化项,旨在阻止网络对某一类别过分自信,即阻止过拟合)。

Inception v4

由于v3无法解决太多类别

Inception v4 和 Inception -ResNet 在同一篇论文《Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning》中介绍。为清晰起见,我们分成两个部分来介绍。

在该论文中,研究者介绍道,Inception 架构可以用很低的计算成本达到很高的性能。而在传统的网络架构中引入残差连接曾在 2015ILSVRC 挑战赛中获得当前最佳结果,其结果和 Inception-v3 网络当时的最新版本相近。这使得人们好奇,如果将 Inception 架构和残差连接结合起来会是什么效果。在这篇论文中,研究者通过实验明确地证实了,结合残差连接可以显著加速 Inception 的训练。也有一些证据表明残差 Inception 网络在相近的成本下略微超过没有残差连接的 Inception 网络。研究者还展示了多种新型残差和非残差 Inception 网络的简化架构。这些变体显著提高了在 ILSVRC2012 分类任务挑战赛上的单帧识别性能。作者进一步展示了适当的激活值缩放如何稳定非常宽的残差 Inception 网络的训练过程。通过三个残差和一个 Inception v4 的模型集成,作者在 ImageNet 分类挑战赛的测试集上取得了 3.08% 的 top-5 误差率。

论文:Inception-v4, Inception-ResNet and the Impact of Residual Connections on Learning

论文地址:https://arxiv.org/pdf/1602.07261.pdf

Inception-ResNet v1 和 v2

受 ResNet 的优越性能启发,研究者提出了一种混合 inception 模块。Inception ResNet 有两个子版本:v1 和 v2。在我们分析其显著特征之前,先看看这两个子版本之间的微小差异。

Inception-ResNet v1 的计算成本和 Inception v3 的接近。Inception-ResNetv2 的计算成本和 Inception v4 的接近。它们有不同的 stem,正如 Inception v4 部分所展示的。两个子版本都有相同的模块 A、B、C 和缩减块结构。唯一的不同在于超参数设置。在这一部分,我们将聚焦于结构,并参考论文中的相同超参数设置(图像是关于 Inception-ResNet v1 的)。

问题:

引入残差连接,它将 inception 模块的卷积运算输出添加到输入上。

解决方案:

为了使残差加运算可行,卷积之后的输入和输出必须有相同的维度。因此,我们在初始卷积之后使用 1x1 卷积来匹配深度(深度在卷积之后会增加)。

V1

1.使用更简单的inception模型。并且每个inception分支后面都跟着一个1x1线性卷积层(就是不带激活函数的卷积层),这是为了匹配输入时的维度,因为残差分支是直接将输入送给输出,但是inception这边很明显进行通道压缩了,所以要通过1x1卷积重新扩增到输入时的维度,用原文话说就是,补偿inception模块带来的降维。

2.它说如果通道数量超过1000时,这个inception-resnet就会失去稳定,并且在训练的早期死亡,死亡意指几千次迭代后在平均池化前的最后一层会开始完全零化,就是只产生很小的数。并且这种现象无法被避免,无论是调低学习率还是增加批次归一化在这一层。但是他们发现如果在将其添加到前一层激活函数之前进行缩小似乎就能稳定训练,一般他们会挑选一些0.1到0.3之间的缩放系数在进行累加层激活之前来压缩inception-resnet模组。

Reduction-A:

inception-resnet-A:

1.使用更简单的inception模型。并且每个inception分支后面都跟着一个1x1线性卷积层(就是不带激活函数的卷积层),这是为了匹配输入时的维度,因为残差分支是直接将输入送给输出,但是inception这边很明显进行通道压缩了,所以要通过1x1卷积重新扩增到输入时的维度,用原文话说就是,补偿inception模块带来的降维。

2.它说如果通道数量超过1000时,这个inception-resnet就会失去稳定,并且在训练的早期死亡,死亡意指几千次迭代后在平均池化前的最后一层会开始完全零化,就是只产生很小的数。并且这种现象无法被避免,无论是调低学习率还是增加批次归一化在这一层。但是他们发现如果在将其添加到前一层激活函数之前进行缩小似乎就能稳定训练,一般他们会挑选一些0.1到0.3之间的缩放系数在进行累加层激活之前来压缩inception-resnet模组。

Reduction-A:

 

这张图上通道数是变量。这个模组是三个模型共用的,所以不同模型有不同系数。reduction就是减少的意思,这个模组负责减半数据空间尺寸,并且加深通道,不知道从某种程度上我们是否可以将其理解为聚集特征。

inception-resnet-B:

inception-resnet-C:

 

ResNeXt:

文中提出了另外一种维度cardinality,和channel和space的维度不同,cardinality维度主要表示ResNeXt中module的个数。

1.增大Cardinality比增大模型的width或者depth效果更好

2.与 ResNet 相比,ResNeXt 参数更少,效果更好,结构更加简单,更方便设计

Xception:

在Inception V3的基础上提出了Xception(Extreme Inception),基本思想就是通道分离式卷积(depthwise separable convolution operation)。模型参数有微量的减少,减少量很少。精度较Inception V3有提高,但提高不大。卷积的操作上面,主要进行2种变换,空间变换和通道变换而Xception就是在这2个变换上做文章。

1.ception V3是先做1*1的卷积,再做3*3的卷积,这样就先将通道进行了合并,即通道卷积,然后再进行空间卷积,而Xception则正好相反,先进行空间的3*3卷积,再进行通道的1*1卷积。

2.这个区别是最不一样的,Inception V3在每个module中都有RELU操作,而Xception在每个module中是没有RELU操作的。

mobilenets:

MobileNets其实就是Exception思想的应用。区别就是Exception文章重点在提高精度,而MobileNets重点在压缩模型,同时保证精度。obileNets模型基于深度可分解的卷积,它可以将标准卷积分解成一个深度卷积和一个点卷积(1 × 1卷积核)。深度卷积将每个卷积核应用到每一个通道,而1 × 1卷积用来组合通道卷积的输出。

宽度乘数:

这里介绍模型的第一个超参数,即宽度乘数 α 。为了构建更小和更少计算量的网络,作者引入了宽度乘数 α ,作用是改变输入输出通道数,减少特征图数量,让网络变瘦。在 α 参数作用下,MobileNets某一层的计算量为:

DK×DK×αM×DF×DF+αM×αN×DF×DF

其中, α 取值是0~1,应用宽度乘数可以进一步减少计算量,大约有 α2 的优化空间。

分辨率乘数:

第二个超参数是分辨率乘数 ρ ,分辨率乘数用来改变输入数据层的分辨率,同样也能减少参数。在 α 和 ρ 共同作用下,MobileNets某一层的计算量为:

DK×DK×αM×ρDF×ρDF+αM×αN×ρDF×ρDF

其中,ρ 是隐式参数,ρ 如果为{1,6/7,5/7,4/7},则对应输入分辨率为{224,192,160,128},ρ 参数的优化空间同样是 ρ2 左右。 表3可以看出两个超参数在减少网络参数的上的作用。

 

参考文献:

(第3个为LeNet-5,第4个为AlexNet,第5个VGG,)

https://www.e-learn.cn/content/qita/725036

http://www.360doc.com/content/18/0402/16/48868863_742310994.shtml

https://blog.csdn.net/happyorg/article/details/78274066 

https://blog.csdn.net/u012679707/article/details/80793916

https://blog.csdn.net/u013181595/article/details/80974210

http://baijiahao.baidu.com/s?id=1601882944953788623&wfr=spider&for=pc


推荐阅读
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 2018年9月21日,Destoon官方发布了安全更新,修复了一个由用户“索马里的海贼”报告的前端GETShell漏洞。该漏洞存在于20180827版本的某CMS中,攻击者可以通过构造特定的HTTP请求,利用该漏洞在服务器上执行任意代码,从而获得对系统的控制权。此次更新建议所有用户尽快升级至最新版本,以确保系统的安全性。 ... [详细]
  • 如何使用 `org.eclipse.rdf4j.query.impl.MapBindingSet.getValue()` 方法及其代码示例详解 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 为了在Hadoop 2.7.2中实现对Snappy压缩和解压功能的原生支持,本文详细介绍了如何重新编译Hadoop源代码,并优化其Native编译过程。通过这一优化,可以显著提升数据处理的效率和性能。此外,还探讨了编译过程中可能遇到的问题及其解决方案,为用户提供了一套完整的操作指南。 ... [详细]
  • 本文详细探讨了Oracle数据库中Number和Float数据类型的特性和使用方法。通过对比分析,解释了Number类型在精度和范围上的优势,以及Float类型在处理科学计算时的灵活性。文章还介绍了Number数据类型的语法结构及其在实际应用中的最佳实践,帮助读者更好地理解和选择合适的数据类型以满足不同的业务需求。 ... [详细]
  • 本文深入探讨了如何利用Maven高效管理项目中的外部依赖库。通过介绍Maven的官方依赖搜索地址(),详细讲解了依赖库的添加、版本管理和冲突解决等关键操作。此外,还提供了实用的配置示例和最佳实践,帮助开发者优化项目构建流程,提高开发效率。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 在本地环境中部署了两个不同版本的 Flink 集群,分别为 1.9.1 和 1.9.2。近期在尝试启动 1.9.1 版本的 Flink 任务时,遇到了 TaskExecutor 启动失败的问题。尽管 TaskManager 日志显示正常,但任务仍无法成功启动。经过详细分析,发现该问题是由 Kafka 版本不兼容引起的。通过调整 Kafka 客户端配置并升级相关依赖,最终成功解决了这一故障。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • 本文探讨了 Java 中 Pair 类的历史与现状。虽然 Java 标准库中没有内置的 Pair 类,但社区和第三方库提供了多种实现方式,如 Apache Commons 的 Pair 类和 JavaFX 的 javafx.util.Pair 类。这些实现为需要处理成对数据的开发者提供了便利。此外,文章还讨论了为何标准库未包含 Pair 类的原因,以及在现代 Java 开发中使用 Pair 类的最佳实践。 ... [详细]
  • AIX编程挑战赛:AIX正方形问题的算法解析与Java代码实现
    在昨晚的阅读中,我注意到了CSDN博主西部阿呆-小草屋发表的一篇文章《AIX程序设计大赛——AIX正方形问题》。该文详细阐述了AIX正方形问题的背景,并提供了一种基于Java语言的解决方案。本文将深入解析这一算法的核心思想,并展示具体的Java代码实现,旨在为参赛者和编程爱好者提供有价值的参考。 ... [详细]
author-avatar
丁志翔64164
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有