草庐IT

AlexNet—论文分析及复现

叶小小qaq 2023-03-28 原文

AlexNet卷积神经网络是由Alex Krizhevsky等人在2012年的ImagNet图像识别大赛获得冠军的一个卷积神经网络,该网络放到现在相对简单,但也是深度学习不错的卷积神经网络。论文:《ImageNet Classification with Deep Convolutional Neural Networks》

论文结构

  • Abstruct:简单介绍了AlexNet的结构及其成果

  • Introduction:神经网络要是有更快的GPU和更大的数据集我们的结果就会得到改善

  • The Dataset:介绍ILSVRC-2010和ImageNet数据集

  • The Architecture:ReLU非线性函数介绍、两个GPU进行训练、局部响应归一化、 Overlapping Pooling、整体架构

  • Reducing Overfitting:对抗过度拟合的方法,数据增强和Dropout

  • Details of learning:超参数的设置,权重及偏置的初始化

  • Results:介绍了AlexNet在比赛中获得的成果,性能评估(Qualitative Evaluations):显示预测正确的概率,同一类的图像特征的欧式距离更近

  • Discussion:结果有了很大的改善,但是在某些方面还是有很多工作要做

AlexNet卷积神经网络的特点

1.非线性激活函数ReLu

  在AlexNet出现之前,sigmoid是最为常用的非线性激活函数。sigmoid函数能够把输入的连续实值压缩到0和1之间。但是,它的缺点也非常明显:当神经网络层数过多或输入值非常大或者非常小的时候会出现饱和现象,即这些神经元的梯度接近0,因此存在梯度消失问题。

\[f(x)=\frac{1}{1+e^{-x}} \]

图像代码:

import numpy as np
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1/(1+np.exp(-x))

x=np.arange(-5.0,5.0,0.1)
y=sigmoid(x)
plt.plot(x,y)
plt.ylim(-0.1,1.1)
plt.show()

图像:

  tanh函数(双曲正切激活函数)很像是sigmoid函数的放大版。在实际使用中要略微优于sigmoid函数,因为它解决的中心对称问题。指数的计算复杂,计算成本高。梯度消失(梯度弥散)的特点依旧保留,因为两边的饱和性使得梯度消失,进而难以训练。

\[f(x)=\frac{e^{x}-e^{-x}}{e^{x}+e^{-x}} \]

图像代码:

import numpy as np
import matplotlib.pyplot as plt

def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))

x=np.arange(-5.0,5.0,0.1)
y=tanh(x)
plt.plot(x,y)
plt.show()

图像:

具体来说ReLU的好处有以下几点:

1.可以使神经网络训练更快

  相比较于sigmoid和tanh,relu的求导速度更快

2.增加神经网络的非线性

  ReLU是非线性函数

\[f(x)=max(0,x) \]

图像代码:

import numpy as np
import matplotlib.pyplot as plt

def relu(x):
    return np.maximum(0,x)

x=np.arange(-5.0,5.0,0.1)
y=relu(x)
plt.plot(x,y)
plt.show()

图像:

3.使神经网络具有稀疏性

  可以使一些神经元输出为0,可以增加网络的稀疏性

4.防止梯度消失

  当数值过大或者过小时,sigmoid, tanh导数接近0, 会导致方向传播时梯度消失的问题,relu为非饱和激活函数不存在此问题

该图表明,如果我们使用传统的饱和神经元模型,我们将无法进行有如此大的神经网络的实验

2.Local Response Normalization(局部响应归一化)

  局部响应归一化(local response normalization,LRN)的思想来源于生物学中的“侧抑制”,是指被激活的神经元抑制相邻的神经元。采用LRN的目的是,将数据分布调整到合理的范围内,便于计算处理,从而提高泛化能力。在神经网络中,我们用激活函数将神经元的输出做一个非线性映射,但是tanh和sigmoid这些传统的激活函数的值域都是有范围的,但是ReLU激活函数得到的值域没有一个区间,可以在[ 0 , ∞ ],所以要对ReLU得到的结果进行归一化。简单理解,就是将利用当前第i个kernel的相邻n − 1个kernel对应(x,y) 的值来做归一化。论文中也给出了公式及介绍:

  在2015年 Very Deep Convolutional Networks for Large-Scale Image Recognition.提到LRN基本没什么用,故这里不做叙述。

  在后来出现的一些CNN架构模型中LRN已不再使用,因为出现了更有说服力的归一化——批量归一化,即BN。

3.两个GPU同时训练

  经过上述可知,两 GPU 网络的训练时间比单 GPU 网络略短。

4.Overlapping Pooling(重叠池化)

  相对于传统的no-overlapping pooling,采用Overlapping Pooling不仅可以提升预测精度,同时一定程度上可以减缓过拟合

  相比于正常池化(步长s=2,窗口z=2) 重叠池化(步长s=2,窗口z=3) 可以减少top-1, top-5分别为0.4% 和0.3%;重叠池化可以避免过拟合。

5.Data Augmentation(数据增强)

 论文中提到了两种形式的Data Augmentation


  随机地从256 × 256的原始图像中截取224 × 224大小的区域(以及水平翻转的镜像),相当于增加了\(2×(256-224)^{2}=2048\)倍的数据量,大大减轻过拟合,提升泛化能力。在进行测试的时候,取图片的四个角加中间一共5个位置,并进行左右翻转,一共获得10张图片,对他们在softmax层进行10次预测结果并求均值。

  对图像的RGB数据进行PCA处理,并对主成分做一个标准差为0.1的高斯扰动,增加一些噪声,可以让错误率再下降1%。其中 pi 和 λi 是 RGB 像素值的 3 × 3 协方差矩阵的第 i 个特征向量和特征值,对于特定训练图像的所有像素,每个 αi 仅绘制一次,直到该图像再次用于训练,此时将重新绘制它。

6.Dropout

  dropout可以让模型训练时,随机让网络上的一些节点失效(输出置零),此时的权重值不会更新,但会保存下来,因为这个过程只是对于本次训练。

  通常会给dropout设置一个比率为p,也就是说每个节点都有p的概率将会失效,这种技术减少了神经元的复杂协同适应,因为一个神经元不能依赖于特定其他神经元的存在。

如果没有 dropout,我们的网络将表现出严重的过拟合。

AlexNet网络结构

第一层卷积

  原论文中,AlexNet的输入图像尺寸是224x224x3。但是实际图像尺寸为227x227x3,具体原因就不深究了,反正224x224x3不能推,227x227x3可以推。

  第一个卷积层为11x11x3,即卷积核尺寸为11x11,有96个卷积核,步长为4,卷积层后紧跟ReLU,因此输出的尺寸为 (227-11)/4+1=55,因此其输出的每个特征图为 55x55x96,同时后面经过LRN层处理,尺寸不变。

  最大池化层,池化核大小为3x3,步长为2,输出的尺寸为 (55-3)/2+1=27,因此特征图的大小为:27x27x96。由于双gpu处理,故每组数据有27x27x48个特征图,共两组数据,分别在两个gpu中进行运算。

第二层卷积

  每组输入的数据为27x27x48,共两组数据,在两个GPU上训练

  每组数据都被128个卷积核大小为: 5x5x48进行卷积运算,步长为1,尺寸不会改变,同样紧跟ReLU,和LRN层进行处理

  最大池化层,池化核大小为3x3,步长为2,因此输出两组特征图:13x13x128

第三——五层卷积

  输入的数据为13x13x128,共两组,分别在两个GPU上

  第三层每组数据都被尺寸为 3x3x192的卷积核进行卷积运算,步长为1,加上ReLU,得到两组13x13x192的像素层

  第四层经过padding=1填充后,每组数据都被尺寸大小为 3x3x192的卷积核卷积运算,步长为1,加上ReLU,输出两组13x13x192的像素层

  第五层经过padding=1填充后,每组数据都被尺寸大小为 3x3x128的卷积核进行卷积运算,步长为1,加上ReLU,输出两组13x13x128的像素层

  经过3x3池化窗口,步长为2,池化后输出两组6x6x256的像素层

第六——八层全连接层

  第六层:4096 个神经元+ ReLU
  第七层:4096个神经元 + ReLU
  第八层:1000 个神经元,最后一层为softmax为1000类的概率值

实现代码

采用的数据集为Fashion-MNIST,数据集地址为:Fashion-MNIST

利用tensorflow对AlexNet神经网络进行简易实现

import tensorflow as tf
import numpy as np


# 加载数据
class DataLoader():
    def __init__(self):
        fashion_mnist = tf.keras.datasets.fashion_mnist
        (self.train_images, self.train_labels), (self.test_images, self.test_labels) = fashion_mnist.load_data()
        self.train_images = np.expand_dims(self.train_images.astype(np.float32)/255.0,axis=-1)
        self.test_images = np.expand_dims(self.test_images.astype(np.float32)/255.0,axis=-1)
        self.train_labels = self.train_labels.astype(np.int32)
        self.test_labels = self.test_labels.astype(np.int32)
        self.num_train, self.num_test = self.train_images.shape[0], self.test_images.shape[0]

    def get_batch_train(self, batch_size):
        index = np.random.randint(0, np.shape(self.train_images)[0], batch_size)
        #need to resize images to (224,224)
        resized_images = tf.image.resize_with_pad(self.train_images[index],224,224,)
        return resized_images.numpy(), self.train_labels[index]

    def get_batch_test(self, batch_size):
        index = np.random.randint(0, np.shape(self.test_images)[0], batch_size)
        #need to resize images to (224,224)
        resized_images = tf.image.resize_with_pad(self.test_images[index],224,224,)
        return resized_images.numpy(), self.test_labels[index]
        
dataLoader = DataLoader()


# 搭建模型
net = tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(filters=96,kernel_size=11,strides=4,activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    tf.keras.layers.Conv2D(filters=256,kernel_size=5,padding='same',activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    tf.keras.layers.Conv2D(filters=384,kernel_size=3,padding='same',activation='relu'),
    tf.keras.layers.Conv2D(filters=384,kernel_size=3,padding='same',activation='relu'),
    tf.keras.layers.Conv2D(filters=256,kernel_size=3,padding='same',activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=3, strides=2),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(4096,activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(4096,activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(10,activation='sigmoid')
])


# 超参数
batch_size = 128
learning_rate = 0.01
momentum=0.0
epoch=20
checkpoint = 20


# 训练
def train_alexnet():
    num_iter = dataLoader.num_train//batch_size
    for e in range(epoch):
        for n in range(num_iter):
            x_batch, y_batch = dataLoader.get_batch_train(batch_size)
            net.fit(x_batch, y_batch)
            if n%checkpoint == 0:
                net.save_weights("alexnet_weights.h5")
                
optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate, momentum=momentum, nesterov=False)

net.compile(optimizer=optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])


train_alexnet()


# 加载并评估
net.load_weights("alexnet_weights.h5")
x_test, y_test = dataLoader.get_batch_test(2000)
net.evaluate(x_test, y_test, verbose=2)

运行中:


比较详细的代码:

# -*- coding=UTF-8 -*-  
import tensorflow as tf  
# 输入数据  
import input_data

  
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)  
# 定义网络超参数  
learning_rate = 0.001  
training_iters = 200000  
batch_size = 64  
display_step = 20  
# 定义网络参数  
n_input = 784  # 输入的维度  
n_classes = 10 # 标签的维度  
dropout = 0.8  # Dropout 的概率  
# 占位符输入  
x = tf.placeholder(tf.types.float32, [None, n_input])  
y = tf.placeholder(tf.types.float32, [None, n_classes])  
keep_prob = tf.placeholder(tf.types.float32)  
# 卷积操作  
def conv2d(name, l_input, w, b):  
    return tf.nn.relu(tf.nn.bias_add( \  
    tf.nn.conv2d(l_input, w, strides=[1, 1, 1, 1], padding='SAME'),b) \  
    , name=name)  
# 最大下采样操作  
def max_pool(name, l_input, k):  
    return tf.nn.max_pool(l_input, ksize=[1, k, k, 1], \  
    strides=[1, k, k, 1], padding='SAME', name=name)  
# 归一化操作  
def norm(name, l_input, lsize=4):  
    return tf.nn.lrn(l_input, lsize, bias=1.0, alpha=0.001 / 9.0, beta=0.75, name=name)  
# 定义整个网络   
def alex_net(_X, _weights, _biases, _dropout):  
    _X = tf.reshape(_X, shape=[-1, 28, 28, 1]) # 向量转为矩阵  
    # 卷积层  
    conv1 = conv2d('conv1', _X, _weights['wc1'], _biases['bc1'])  
    # 下采样层  
    pool1 = max_pool('pool1', conv1, k=2)  
    # 归一化层  
    norm1 = norm('norm1', pool1, lsize=4)  
    # Dropout  
    norm1 = tf.nn.dropout(norm1, _dropout)  
   
    # 卷积  
    conv2 = conv2d('conv2', norm1, _weights['wc2'], _biases['bc2'])  
    # 下采样  
    pool2 = max_pool('pool2', conv2, k=2)  
    # 归一化  
    norm2 = norm('norm2', pool2, lsize=4)  
    # Dropout  
    norm2 = tf.nn.dropout(norm2, _dropout)  
   
    # 卷积  
    conv3 = conv2d('conv3', norm2, _weights['wc3'], _biases['bc3'])  
    # 下采样  
    pool3 = max_pool('pool3', conv3, k=2)  
    # 归一化  
    norm3 = norm('norm3', pool3, lsize=4)  
    # Dropout  
    norm3 = tf.nn.dropout(norm3, _dropout)  
   
    # 全连接层,先把特征图转为向量  
    dense1 = tf.reshape(norm3, [-1, _weights['wd1'].get_shape().as_list()[0]])   
    dense1 = tf.nn.relu(tf.matmul(dense1, _weights['wd1']) + _biases['bd1'], name='fc1')   
    # 全连接层  
    dense2 = tf.nn.relu(tf.matmul(dense1, _weights['wd2']) + _biases['bd2'], name='fc2') 
    # Relu activation  
    # 网络输出层  
    out = tf.matmul(dense2, _weights['out']) + _biases['out']  
    return out  
   
# 存储所有的网络参数  
weights = {  
    'wc1': tf.Variable(tf.random_normal([3, 3, 1, 64])),  
    'wc2': tf.Variable(tf.random_normal([3, 3, 64, 128])),  
    'wc3': tf.Variable(tf.random_normal([3, 3, 128, 256])),  
    'wd1': tf.Variable(tf.random_normal([4*4*256, 1024])),  
    'wd2': tf.Variable(tf.random_normal([1024, 1024])),  
    'out': tf.Variable(tf.random_normal([1024, 10]))  
}  
biases = {  
    'bc1': tf.Variable(tf.random_normal([64])),  
    'bc2': tf.Variable(tf.random_normal([128])),  
    'bc3': tf.Variable(tf.random_normal([256])),  
    'bd1': tf.Variable(tf.random_normal([1024])),  
    'bd2': tf.Variable(tf.random_normal([1024])),  
    'out': tf.Variable(tf.random_normal([n_classes]))  
}  
# 构建模型  
pred = alex_net(x, weights, biases, keep_prob)  
# 定义损失函数和学习步骤  
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y))  
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)  
# 测试网络  
correct_pred = tf.equal(tf.argmax(pred,1), tf.argmax(y,1))  
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))  
# 初始化所有的共享变量  
init = tf.initialize_all_variables()  
# 开启一个训练  
with tf.Session() as sess:  
    sess.run(init)  
    step = 1  
    # Keep training until reach max iterations  
    while step * batch_size < training_iters:  
        batch_xs, batch_ys = mnist.train.next_batch(batch_size)  
        # 获取批数据  
        sess.run(optimizer, feed_dict={x: batch_xs, y: batch_ys, keep_prob: dropout})  
        if step % display_step == 0:  
            # 计算精度  
            acc = sess.run(accuracy, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 1.})  
            # 计算损失值  
            loss = sess.run(cost, feed_dict={x: batch_xs, y: batch_ys, keep_prob: 1.})  
            print "Iter " + str(step*batch_size) + ", Minibatch Loss= " + "{:.6f}".format(loss) + ", Training Accuracy= " + "{:.5f}".format(acc)  
        step += 1  
    print "Optimization Finished!"  
    # 计算测试精度  
    print "Testing Accuracy:", sess.run(accuracy, feed_dict={x: mnist.test.images[:256], y: mnist.test.labels[:256], keep_prob: 1.})  
 
# 以上代码忽略了部分卷积层,全连接层使用了特定的权重。

注:此来源于百度,仅供学习参考

参考文献

《ImageNet Classification with Deep Convolutional Neural Networks》

本文写于2022年7月27日00:41

有关AlexNet—论文分析及复现的更多相关文章

  1. 建模分析 | 平面2R机器人(二连杆)运动学与动力学建模(附Matlab仿真) - 2

    目录0专栏介绍1平面2R机器人概述2运动学建模2.1正运动学模型2.2逆运动学模型2.3机器人运动学仿真3动力学建模3.1计算动能3.2势能计算与动力学方程3.3动力学仿真0专栏介绍?附C++/Python/Matlab全套代码?课程设计、毕业设计、创新竞赛必备!详细介绍全局规划(图搜索、采样法、智能算法等);局部规划(DWA、APF等);曲线优化(贝塞尔曲线、B样条曲线等)。?详情:图解自动驾驶中的运动规划(MotionPlanning),附几十种规划算法1平面2R机器人概述如图1所示为本文的研究本体——平面2R机器人。对参数进行如下定义:机器人广义坐标

  2. 网站日志分析软件--让网站日志分析工作变得更简单 - 2

    网站的日志分析,是seo优化不可忽视的一门功课,但网站越大,每天产生的日志就越大,大站一天都可以产生几个G的网站日志,如果光靠肉眼去分析,那可能看到猴年马月都看不完,因此借助网站日志分析工具去分析网站日志,那将会使网站日志分析工作变得更简单。下面推荐两款网站日志分析软件。第一款:逆火网站日志分析器逆火网站日志分析器是一款功能全面的网站服务器日志分析软件。通过分析网站的日志文件,不仅能够精准的知道网站的访问量、网站的访问来源,网站的广告点击,访客的地区统计,搜索引擎关键字查询等,还能够一次性分析多个网站的日志文件,让你轻松管理网站。逆火网站日志分析器下载地址:https://pan.baidu.

  3. ABB-IRB-1200运动学分析MATLAB RVC工具分析+Simulink-Adams联合仿真 - 2

    一、机器人介绍        此处是基于MATLABRVC工具箱,对ABB-IRB-1200型号的微型机械臂进行正逆向运动学分析,并利Simulink工具实现对机械臂进行具有动力学参数的末端轨迹规划仿真,最后根据机械模型设计Simulink-Adams联合仿真。 图1.ABBIRB 1200尺寸参数示意图ABBIRB 1200提供的两种型号广泛适用于各作业,且两者间零部件通用,两种型号的工作范围分别为700 mm 和 900 mm,大有效负载分别为 7 kg 和5 kg。 IRB 1200 能够在狭小空间内能发挥其工作范围与性能优势,具有全新的设计、小型化的体积、高效的性能、易于集成、便捷的接

  4. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

  5. ruby-on-rails - 如何使用 ruby​​-prof 和 JMeter 分析 Rails - 2

    我想使用ruby​​-prof和JMeter分析Rails应用程序。我对分析特定Controller/操作/或模型方法的建议方法不感兴趣,我想分析完整堆栈,从上到下。所以我运行这样的东西:RAILS_ENV=productionruby-prof-fprof.outscript/server>/dev/null然后我在上面运行我的JMeter测试计划。然而,问题是使用CTRL+C或SIGKILL中断它也会在ruby​​-prof可以写入任何输出之前杀死它。如何在不中断ruby​​-prof的情况下停止mongrel服务器? 最佳答案

  6. 【Unity游戏破解】外挂原理分析 - 2

    文章目录认识unity打包目录结构游戏逆向流程Unity游戏攻击面可被攻击原因mono的打包建议方案锁血飞天无限金币攻击力翻倍以上统称内存挂透视自瞄压枪瞬移内购破解Unity游戏防御开发时注意数据安全接入第三方反作弊系统外挂检测思路狠人自爆实战查看目录结构用il2cppdumper例子2-森林whoishe后记认识unity打包目录结构dll一般很大,因为里面是所有的游戏功能编译成的二进制码游戏逆向流程开发人员代码被编译打包到GameAssembly.dll中使用il2ppDumper工具,并借助游戏名_Data\il2cpp_data\Metadata\global-metadata.dat

  7. 驱动开发:内核无痕隐藏自身分析 - 2

    在笔者前面有一篇文章《驱动开发:断链隐藏驱动程序自身》通过摘除驱动的链表实现了断链隐藏自身的目的,但此方法恢复时会触发PG会蓝屏,偶然间在网上找到了一个作者介绍的一种方法,觉得有必要详细分析一下他是如何实现的进程隐藏的,总体来说作者的思路是最终寻找到MiProcessLoaderEntry的入口地址,该函数的作用是将驱动信息加入链表和移除链表,运用这个函数即可动态处理驱动的添加和移除问题。MiProcessLoaderEntry(pDriverObject->DriverSection,1)添加MiProcessLoaderEntry(pDriverObject->DriverSection,

  8. micropython复现经典单片机项目(二)可视化音频 频谱解析(基本搞定) - 2

    本人是音乐爱好者,从小就特别喜欢那个随着音乐跳动的方框效果,就是这个:arduino上一大把对,我忍你很久了,我就想用mpy做,全网没有,行我自己研究。果然兴趣是最好的老师,我之前有篇博客专门讲音频,有兴趣的可以回顾一下。提到可视化频谱,必然绕不开fft,大学学过这玩意,当时一心玩,老师讲的一个字都么听进去,网上教程简略扫了一下,大该就是把时域转频域的工具,我大mpy居然没有fft函数,奶奶的,先放着。音频信息如何收集?第一种傻瓜式的ADC,模拟转数字,原始粗暴,第二种,I2S库,我之前博客有讲过,数据是PCM编码。然后又去学PCM编码,一学豁然开朗,舒服,以代码为例:audio_in=I2S

  9. 论文解读OTA: Optimal Transport Assignment for Object Detection - 2

    CSDN优秀解读:https://blog.csdn.net/jiaoyangwm/article/details/1266387752021https://arxiv.org/pdf/2103.14259.pdf关键解读在目标检测中标签分配的最新进展主要寻求为每个GT对象独立定义正/负训练样本。在本文中,我们创新性地从全局的角度重新审视标签分配,并提出将分配程序制定为一个最优传输(OT)问题——优化理论中一个被充分研究的课题。具体来说,我们将每个需求方(锚框)和供应商(GT标签)的单位传输成本定义为他们的分类和回归损失加权之和。在公式化后,找到最好的分配方案即为最小传播成本解决最优传输方案,

  10. 2023爱分析·流程中台市场厂商评估报告:微宏科技 - 2

     目录1. 研究范围定义2. 流程中台市场分析3. 厂商评估:微宏科技4. 入选证书 1.   研究范围定义近年来,随着外部市场环境快速变化、客户需求愈发多样,企业逐渐意识到,自身业务需要更加敏捷、高效,具备根据市场需求快速迭代的能力。业务流程的自动化能够帮助企业实现业务的敏捷高效,因此受到越来越多企业的关注。企业的“自动化武器库”品类丰富,包括低/零代码平台、RPA、BPM、AI等。企业可以使用多项自动化工具,但结果往往是各项自动化工具处于各自的“自动化烟囱”之中,仅能实现碎片式自动化。例如,某企业的IT团队可能在使用低代码平台、财务团队可能在使用RPA、呼叫中心则可能在使用聊天机器人。自动

随机推荐