前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >如何使用TensorFlow构建神经网络来识别手写数字

如何使用TensorFlow构建神经网络来识别手写数字

原创
作者头像
宇cccc
修改于 2018-11-16 08:03:15
修改于 2018-11-16 08:03:15
1.7K00
代码可运行
举报
运行总次数:0
代码可运行

介绍

神经网络被用作深度学习的方法,深度学习是人工智能的许多子领域之一。它们大约在70年前首次提出,试图模拟人类大脑的工作方式,尽管它的形式要简化得多。各个“神经元”分层连接,分配权重以确定当信号通过网络传播时神经元如何响应。以前,神经网络在他们能够模拟的神经元数量上受到限制,因此他们可以实现学习的复杂性。但近年来,由于硬件开发的进步,我们已经能够构建非常深的网络,并在大量数据集上训练它们以实现机器智能的突破。

这些突破使机器在执行某些任务时能够匹配并超越人类的能力。一个这样的任务是对象识别。虽然历史上机器无法与人类视觉相匹配,但深度学习的最新进展使得构建可识别物体,面部,文本甚至情绪的神经网络成为可能。

在本教程中,您将实现对象识别 - 数字识别的一小部分。使用由Google Brain实验室开发的用于深度学习研究的开源PythonTensorFlow,您将获取数字0-9的手绘图像,并构建和训练神经网络以识别和预测数字的正确标签显示。

虽然您不需要实际深度学习或TensorFlow的先前经验来跟随本教程,但我们将假设您熟悉机器学习术语和概念,例如培训和测试,功能和标签,优化和评估。

先决条件

要完成本教程,您需要:

第1步 - 配置项目

在开发识别程序之前,您需要安装一些依赖项并创建一个工作区来保存文件。

我们将使用Python 3虚拟环境来管理项目的依赖项。为项目创建一个新目录并导航到新目录:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mkdir tensorflow-demo
cd tensorflow-demo

执行以下命令为本教程设置虚拟环境:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python3 -m venv tensorflow-demo
source tensorflow-demo/bin/activate

接下来,安装您将在本教程中使用的库。我们将通过在项目目录中创建一个requirements.txt文件来使用这些库的特定版本,该文件指定了我们需要的需求和版本。创建requirements.txt文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
touch requirements.txt

在文本编辑器中打开文件并添加以下行以指定Image,NumPy和TensorFlow库及其版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
image==1.5.20
numpy==1.14.3
tensorflow==1.4.0

保存文件并退出编辑器。然后使用以下命令安装这些库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install -r requirements.txt

安装了依赖项后,我们就可以开始处理我们的项目了。

第2步 - 导入MNIST数据集

我们将在本教程中使用的数据集称为MNIST数据集,它是机器学习社区中的经典之作。该数据集由手写数字的图像组成,大小为28x28像素。以下是数据集中包含的数字的一些示例:

让我们创建一个Python程序来处理这个数据集。我们将在本教程中使用一个文件来完成所有工作。创建一个名为main.py的新文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
touch main.py

现在,在您选择的文本编辑器中打开此文件,并将此行代码添加到文件中以导入TensorFlow库:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import tensorflow as tf

将以下代码行添加到文件中以导入MNIST数据集并将图像数据存储mnist变量中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True) # y labels are oh-encoded

在读取数据时,我们使用单热编码来表示图像的标签(绘制的实际数字,例如“3”)。单热编码使用二进制值向量来表示数值或分类值。由于我们的标签用于数字0-9,因此向量包含十个值,每个可能的数字一个。其中一个值设置为1,表示向量索引处的数字,其余值设置为0.例如,数字3使用向量[0, 0, 0, 1, 0, 0, 0, 0, 0, 0]表示。由于索引3处的值存储为1,因此向量表示数字3。

为了表示实际图像本身,将28x28像素平坦化为1D向量,其大小为784像素。构成图像的784个像素中的每一个都存储为0到255之间的值。这决定了像素的灰度,因为我们的图像仅以黑白呈现。因此,黑色像素由255表示,白色像素由0表示,其间有不同的灰色阴影。

我们可以使用mnist变量来找出刚刚导入的数据集的大小。查看三个子集中的每一个的num_examples,我们可以确定数据集已分为55,000个用于训练的图像,5000个用于验证,10,000个用于测试。将以下行添加到您的文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
n_train = mnist.train.num_examples # 55,000
n_validation = mnist.validation.num_examples # 5000
n_test = mnist.test.num_examples # 10,000

现在我们已经导入了数据,现在是时候考虑神经网络了。

第3步 - 定义神经网络架构

神经网络的体系结构指的是诸如网络中的层数,每层中的单元数以及单元如何在层之间连接的元素。由于神经网络受到人类大脑运作的松散启发,因此术语单位用于表示我们在生物学上认为的神经元。就像神经元在大脑周围传递信号一样,单位将先前单位的某些值作为输入,执行计算,然后将新值作为输出传递给其他单位。这些单元分层形成网络,从一层开始输入值,一层输出值。术语隐藏层设置在输入和输出层之间的用于所有的层,即,那些“隐藏”从现实世界。

不同的体系结构可以产生截然不同的结果,因为性能可以被认为是体系结构的函数,例如参数,数据和训练的持续时间。

将以下代码行添加到文件中,以存储全局变量中每层的单元数。这允许我们在一个地方改变网络架构,在本教程结束时,您可以自己测试不同数量的层和单元将如何影响我们模型的结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
n_input = 784   # input layer (28x28 pixels)
n_hidden1 = 512 # 1st hidden layer
n_hidden2 = 256 # 2nd hidden layer
n_hidden3 = 128 # 3rd hidden layer
n_output = 10   # output layer (0-9 digits)

下图显示了我们设计的体系结构的可视化,每个层完全连接到周围的层:

术语“深度神经网络”涉及隐藏层的数量,“浅”通常仅表示一个隐藏层,“深”表示多个隐藏层。给定足够的训练数据,具有足够数量单位的浅层神经网络理论上应该能够表示深度神经网络可以具有的任何功能。但是,使用较小的深度神经网络来实现相同的任务通常需要更高的计算效率,这需要具有指数级隐藏单元的浅网络。浅层神经网络也经常遇到过度拟合,其中网络基本上记忆它已经看到的训练数据,并且不能将知识概括为新数据。这就是深度神经网络更常用的原因:

需要在此定义的神经网络的其他元素是超参数。与在训练期间将更新的参数不同,这些值最初设置并在整个过程中保持不变。在您的文件中,设置以下变量和值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
learning_rate = 1e-4
n_iterations = 1000
batch_size = 128
dropout = 0.5

学习率表示在学习过程的每个步骤中参数将调整很多。这些调整是培训的一个关键组成部分:在每次通过网络后,我们会略微调整权重以尝试减少损失。较大的学习速率可以更快地收敛,但也有可能在更新时超过最佳值。迭代次数是指我们完成训练步骤的次数,批次大小是指我们在每个步骤中使用的训练样例数量。dropout变量代表了我们在随机elimanate一些单位的阈值。我们将在最后的隐藏层中使用dropout,使每个单元在每个训练步骤中有50%的机会被淘汰。这有助于防止过度拟合。

我们现在已经定义了神经网络的架构,以及影响学习过程的超参数。下一步是将网络构建为TensorFlow图。

第4步 - 构建TensorFlow图

为了构建我们的网络,我们将网络设置为TensorFlow执行的计算图。TensorFlow的核心概念是张量,一种类似于数组或列表的数据结构。初始化,在通过图表时进行操作,并通过学习过程进行更新。

我们首先将三个张量定义为占位符,这些张量是我们稍后将值输入的张量。将以下内容添加到您的文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
X = tf.placeholder("float", [None, n_input])
Y = tf.placeholder("float", [None, n_output])
keep_prob = tf.placeholder(tf.float32) 

需要在其声明中指定的唯一参数是我们将在被供给的数据的大小。对于X我们使用[None, 784]的形状,其中None表示的任何量,如我们将在784像素的图像的未定义数量的进料。Y的形状是[None, 10],因为我们将使用它的标签输出的未定义数量的,具有10个可能的类。keep_prob张量是用来控制辍学率,我们初始化它作为一个占位符,而不是一成不变的变量,因为我们想用同样的张量都为训练(当dropout设置为0.5)和测试(当dropout设置为1.0)。

网络将在训练过程中更新的参数是weightbias值,因此对于这些参数,我们需要设置初始值而不是空占位符。这些值基本上是网络学习的地方,因为它们用于神经元的激活功能,代表单元之间连接的强度。

由于在训练期间优化了这些值,我们现在可以将它们设置为零。但初始值实际上对模型的最终准确性有重大影响。我们将使用截断的正态分布中的随机值作为权重。我们希望它们接近于零,因此它们可以在正方向或负方向上调整,并且稍微不同,因此它们会产生不同的错误。这将确保模型学到有用的东西。添加以下行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
weights = {
    'w1': tf.Variable(tf.truncated_normal([n_input, n_hidden1], stddev=0.1)),
    'w2': tf.Variable(tf.truncated_normal([n_hidden1, n_hidden2], stddev=0.1)),
    'w3': tf.Variable(tf.truncated_normal([n_hidden2, n_hidden3], stddev=0.1)),
    'out': tf.Variable(tf.truncated_normal([n_hidden3, n_output], stddev=0.1)),
}

对于偏差,我们使用一个小的常数值来确保张量在初始阶段激活,从而有助于传播。权重和偏差张量存储在字典对象中以便于访问。将此代码添加到您的文件中以定义偏差:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
biases = {
    'b1': tf.Variable(tf.constant(0.1, shape=[n_hidden1])),
    'b2': tf.Variable(tf.constant(0.1, shape=[n_hidden2])),
    'b3': tf.Variable(tf.constant(0.1, shape=[n_hidden3])),
    'out': tf.Variable(tf.constant(0.1, shape=[n_output]))
}

接下来,通过定义将操纵张量的操作来设置网络层。将这些行添加到您的文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
layer_1 = tf.add(tf.matmul(X, weights['w1']), biases['b1'])
layer_2 = tf.add(tf.matmul(layer_1, weights['w2']), biases['b2'])
layer_3 = tf.add(tf.matmul(layer_2, weights['w3']), biases['b3'])
layer_drop = tf.nn.dropout(layer_3, keep_prob)
output_layer = tf.matmul(layer_3, weights['out']) + biases['out']

每个隐藏层将对前一层的输出和当前层的权重执行矩阵乘法,并将偏差添加到这些值。在最后一个隐藏层,我们将使用0.5 的keep_prob值应用一个dropout操作。

构建图形的最后一步是定义我们想要优化的损失函数。TensorFlow程序中流行的损失函数选择是交叉熵,也称为对数损失,它量化了两个概率分布(预测和标签)之间的差异。完美的分类将导致交叉熵为0,并且损失完全最小化。

我们还需要选择将用于最小化损失函数的优化算法。名为梯度下降优化的过程是通过沿负(下降)方向沿梯度采取迭代步骤来找到函数的(局部)最小值的常用方法。在TensorFlow中已经实现了几种梯度下降优化算法,在本教程中我们将使用Adam优化器。这通过使用动量来通过计算梯度的指数加权平均值并在调整中使用该动量来加速该过程,从而扩展梯度下降优化。将以下代码添加到您的文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=output_layer))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

我们现在已经定义了网络并使用TensorFlow构建了它。下一步是通过图形提供数据来训练它,然后测试它实际上已经学到了什么。

第5步 - 培训和测试

训练过程包括通过图形提供训练数据集并优化损失函数。每当网络迭代一批更多的训练图像时,它就会更新参数以减少损失,以便更准确地预测所显示的数字。测试过程包括通过训练图形运行我们的测试数据集,并跟踪正确预测的图像数量,以便我们可以计算准确度。

在开始培训过程之前,我们将定义评估准确性的方法,以便我们在培训时将其打印出小批量数据。这些打印的陈述将允许我们检查从第一次迭代到最后一次,损失减少和准确性增加; 它们还允许我们跟踪我们是否已经运行了足够的迭代来达到一致和最佳的结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
correct_pred = tf.equal(tf.argmax(output_layer, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

correct_pred中,我们通过查看output_layer(预测)和Y(标签)来使用arg_max函数来比较哪些图像被正确预测,我们使用该equal函数将其作为[布尔值]列表返回。然后我们可以将此列表转换为浮点数并计算平均值以获得总精度得分。

我们现在准备初始化运行图的会话。在本次会议中,我们将使用我们的培训示例为网络提供信息,一旦经过培训,我们就会使用新的测试示例提供相同的图表,以确定模型的准确性。将以下代码行添加到您的文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

深度学习中训练过程的本质是优化损失函数。在这里,我们的目标是最小化图像的预测标签和图像的真实标签之间的差异。该过程涉及四个步骤,这些步骤重复一定次数的迭代:

  • 通过网络传播价值
  • 计算损失
  • 通过网络向后传播值
  • 更新参数

在每个训练步骤中,稍微调整参数以尝试减少下一步的损失。随着学习的进展,我们应该看到损失减少,最终我们可以停止培训并使用网络作为测试新数据的模型。

将此代码添加到文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# train on mini batches
for i in range(n_iterations):
    batch_x, batch_y = mnist.train.next_batch(batch_size)
    sess.run(train_step, feed_dict={X: batch_x, Y: batch_y, keep_prob:dropout})
​
    # print loss and accuracy (per minibatch)
    if i%100==0:
        minibatch_loss, minibatch_accuracy = sess.run([cross_entropy, accuracy], feed_dict={X: batch_x, Y: batch_y, keep_prob:1.0})
        print("Iteration", str(i), "\t| Loss =", str(minibatch_loss), "\t| Accuracy =", str(minibatch_accuracy))

在每个培训步骤100次迭代后,我们通过网络提供一小批图像,我们打印出该批次的损失和准确性。请注意,我们不应期望减少损失并提高准确性,因为值是按批次而不是整个模型。我们使用小批量图像而不是单独提供它们以加快训练过程并允许网络在更新参数之前看到许多不同的示例。

培训完成后,我们可以在测试图像上运行会话。这次我们使用keep_prob辍学率1.0来确保所有单位在测试过程中都处于活动状态。

将此代码添加到文件中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
test_accuracy = sess.run(accuracy, feed_dict={X: mnist.test.images, Y: mnist.test.labels, keep_prob:1.0})
print("\nAccuracy on test set:", test_accuracy)

现在是时候运行我们的程序,看看我们的神经网络能够准确识别这些手写数字。保存main.py文件并在终端中执行以下命令以运行脚本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
python3 main.py

虽然单个损失和准确度结果可能略有不同,但您会看到类似于以下内容的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Iteration 0     | Loss = 3.67079    | Accuracy = 0.140625
Iteration 100   | Loss = 0.492122   | Accuracy = 0.84375
Iteration 200   | Loss = 0.421595   | Accuracy = 0.882812
Iteration 300   | Loss = 0.307726   | Accuracy = 0.921875
Iteration 400   | Loss = 0.392948   | Accuracy = 0.882812
Iteration 500   | Loss = 0.371461   | Accuracy = 0.90625
Iteration 600   | Loss = 0.378425   | Accuracy = 0.882812
Iteration 700   | Loss = 0.338605   | Accuracy = 0.914062
Iteration 800   | Loss = 0.379697   | Accuracy = 0.875
Iteration 900   | Loss = 0.444303   | Accuracy = 0.90625
​
Accuracy on test set: 0.9206

为了尝试提高模型的准确性,或者想要了解调整超参数的影响的更多信息,我们可以测试更改学习速率,退出阈值,批量大小和迭代次数的效果。我们还可以更改隐藏层中的单元数,并更改隐藏层本身的数量,以查看不同架构如何增加或降低模型精度。

为了证明网络实际上是在识别手绘图像,让我们在我们自己的单个图像上进行测试。

首先要么下载这个样本测试图像,要么打开图形编辑器并创建一个自己的28x28像素的数字图像。

在编辑器中打开main.py文件,并将以下代码行添加到文件顶部,以导入图像处理所需的两个库。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
from PIL import Image
...

然后在文件末尾添加以下代码行以加载手写数字的测试图像:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
img = np.invert(Image.open("test_img.png").convert('L')).ravel()

Image库的open功能将测试图像加载为包含三个RGB颜色通道和Alpha透明度的4D阵列。这与我们之前在使用TensorFlow读取数据集时使用的表示不同,因此我们需要做一些额外的工作来匹配格式。

首先,我们使用带L参数的convert函数将4D RGBA表示减少到一个灰度颜色通道。我们将其存储为numpy数组并使用np.invert进行反转,因为当前矩阵将黑色表示为0,将白色表示为255,而我们则需要相反。最后,我们调用ravel来排列数组。

现在图像数据结构正确,我们可以像以前一样运行会话,但这次只能在单个图像中进行测试。将以下代码添加到您的文件中以测试图像并打印输出的标签。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
prediction = sess.run(tf.argmax(output_layer,1), feed_dict={X: [img]})
print ("Prediction for test image:", np.squeeze(prediction))

在预测上调用np.squeeze函数以从数组返回单个整数(即从[2]变为2)。结果输出表明网络已将此图像识别为数字2。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Prediction for test image: 2

您可以尝试使用更复杂的图像测试网络 - 例如,看起来像其他数字的数字,或者绘制得很差或不正确的数字 - 以查看它的票价。

结论

在本教程中,您成功地训练了一个神经网络,对MNIST数据集进行了大约92%的准确度分类,并在您自己的图像上进行了测试。当前最先进的研究使用涉及卷积层的更复杂的网络架构,在同一问题上实现了大约99%的研究。这些使用图像的2D结构来更好地表示内容,不像我们将所有像素平铺成784个单位的一个矢量的方法。您可以在TensorFlow网站上阅读有关此主题的更多信息,并查看详细介绍MNIST网站上最准确结果的研究论文。

既然您已经知道如何构建和训练神经网络,您可以尝试在您自己的数据上使用此实现,或者在其他流行的数据集上进行测试,例如Google StreetView House NumbersCIFAR-10数据集以获得更一般的图像承认。

想要了解更多使用TensorFlow构建神经网络来识别手写数字的相关教程,请前往腾讯云+社区学习更多知识。


参考文献:《How To Build a Neural Network to Recognize Handwritten Digits with TensorFlow》

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
SpringCloud常见面试题及答案
单个轻量级服务一般为一个单独微服务,微服务讲究的是 专注某个功能的实现,比如登录系统只专注于用户登录方面功能的实现,讲究的是职责单一,开箱即用,可以独立运行。微服务架构系统是一个分布式的系统,按照业务进行划分服务单元模块,解决单个系统的不足,满足越来越复杂的业务需求。
用户4283147
2022/10/27
6750
SpringCloud常见面试题及答案
查漏补缺:2020年搞定SpringCloud面试(含答案和思维导图)
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
程序员追风
2019/12/30
8730
查漏补缺:2020年搞定SpringCloud面试(含答案和思维导图)
精选SpringCloud面试题
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
一行Java
2022/04/07
6500
精选SpringCloud面试题
Spring Cloud面试题万字解析(2020面试必备)
Spring cloud 流应用程序启动器是 于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。
程序员追风
2020/05/12
1.1K0
Spring Cloud面试题万字解析(2020面试必备)
Spring Cloud面试题(2020最新版)
Java面试总结汇总,整理了包括Java基础知识,集合容器,并发编程,JVM,常用开源框架Spring,MyBatis,数据库,中间件等,包含了作为一个Java工程师在面试中需要用到或者可能用到的绝大部分知识。欢迎大家阅读,本人见识有限,写的博客难免有错误或者疏忽的地方,还望各位大佬指点,在此表示感激不尽。文章持续更新中…
Java架构师必看
2020/04/10
2.5K0
微服务常见面试题
微服务通信机制 系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。 围绕业务能力组织服务、自动化部署、智能端点、对语言及数据的去集中化控制。
用户7353950
2022/05/11
5790
微服务常见面试题
2022年Java秋招面试求职必看的Spring Cloud 面试题
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
Java程序猿
2022/07/10
6440
2022 最新 Spring Cloud 面试题 (一)
Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序, 提供与外部系统的集成。 Spring cloud Task, 一个生命周期短暂的微服务框架 , 用于快速构建执行有限数据处理的应用程序。
猫头虎
2024/04/07
1520
2022 最新 Spring Cloud 面试题 (一)
如何在面试中回答Spring Cloud问题?
Spring cloud流应用程序启动器是基于Spring Boot的Spring集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。
用户5927304
2019/07/30
8530
如何在面试中回答Spring Cloud问题?
面试反馈 Spring Cloud 的25连环炮
前段时间由于特殊原因,导致我们的面试连环炮断更了,刚好上周一位老铁去面试被问到了Spring Cloud,然后结合他的反馈,今天我们继续走起SpringCloud面试连环炮。
田维常
2021/07/15
5740
SpringCloud全网讲解最详细的一般---包面试稳过
👨‍🎓作者:Java学术趴 🏦仓库:Github、Gitee ✏️博客:CSDN、掘金、InfoQ、云+社区 💌公众号:Java学术趴 🚫特别声明:原创不易,未经授权不得转载或抄袭,如需转载可联系小编授权。 🙏版权声明:文章里的部分文字或者图片来自于互联网以及百度百科,如有侵权请尽快联系小编。 ☠️每日毒鸡汤:这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的! 👋大家好!我是你们的老朋友Java学术趴,又到了一年一度最佳找工作的时节,你拿到心仪的offer了吗?基于大多数粉丝
Java学术趴
2022/05/24
3310
SpringCloud全网讲解最详细的一般---包面试稳过
SpringCloud基础组件总结,与Dubbo框架、Boot框架对比分析
Eureka组件,服务注册与发现 Ribbon和Feign组件,实现负载均衡 Hystrix组件,实现服务熔断 Turbine组件,实现微服务集群监控 Zuul组件,实现路由网关控制 Config组件,实现配置统一管理 Zipkin组件,实现请求链路追踪 2)、应用案例 基于Shard-Jdbc分库分表,数据库扩容方案 基于SpringCloud实现Shard-Jdbc的分库分表扩容
知了一笑
2019/08/29
1.1K0
SpringCloud基础组件总结,与Dubbo框架、Boot框架对比分析
Spring Cloud面试题(2021最新版)
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Java程序猿
2021/04/18
22.9K3
Java面试集锦(一)之SpringCloud
服务在发布时 指定对应的服务名(服务名包括了IP地址和端口) 将服务注册到注册中心(eureka或者zookeeper) 这一过程是springcloud自动实现 只需要在main方法添加@EnableDisscoveryClient 同一个服务修改端口就可以启动多个实例 调用方法:传递服务名称通过注册中心获取所有的可用实例 通过负载均衡策略调用(ribbon和feign)对应的服务
凯哥Java
2022/12/16
3640
Java面试集锦(一)之SpringCloud
10道面试官喜欢问的微服务面试题Spring Cloud+Spring Boot
随着互联网的快速发展,各行各业都在用互联网。互联网已经离不开人们的形形色色。随着越来越多的用户,业务场景也愈来愈复杂。
程序员追风
2019/07/25
4.2K0
你是时候该学习SpringCloud
目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事。
Java编程指南
2019/08/05
5840
SpringCloud与Dubbo的区别[通俗易懂]
SpringCloud生态丰富,功能完善,更像是品牌机,Dubbo则相对灵活,可定制性强,更像是组装机。相关资料:
全栈程序员站长
2022/07/01
1K0
Spring Cloud 面试必知必会35个问,你能答上几个?
Spring Cloud为开发人员提供了工具,以快速构建分布式系统中的一些常见模式(例如,配置管理,服务发现,断路器,智能路由,微代理,控制总线,一次性令牌,全局锁,领导选举,分布式会话,群集状态)。它们可以在任何分布式环境中正常工作,包括开发人员自己的笔记本电脑,裸机数据中心以及Cloud Foundry等托管平台。
Java小咖秀
2020/07/01
7940
Spring Cloud 面试必知必会35个问,你能答上几个?
SpringBoot+SpringCloud面试题整理
什么是SpringBoot? 1、用来简化spring初始搭建和开发过程使用特定的方式进行配置(properties或者yml文件) 2、创建独立的spring引用程序main方法运行 3、嵌入Tomcat无需部署war包,直接打成jar包nohup java -jar – & 启动就好 4、简化了maven的配置 4、自动配置spring添加对应的starter自动化配置 SpringBoot常用的starter: 1、spring-boot-starter-web(嵌入Tomcat和web开发需要的servlet和jsp支持) 2、spring-boot-starter-data-jpa(数据库支持) 3、spring-boot-starter-data-Redis(Redis支持) 4、spring-boot-starter-data-solr(solr搜索应用框架支持) 5、mybatis-spring-boot-starter(第三方mybatis集成starter) SpringBoot自动配置原理: 1、@EnableAutoConfiguration这个注解会”猜”你将如何配置spring,前提是你已经添加了jar依赖项,如果spring-boot-starter-web已经添加Tomcat和SpringMVC,这个注释就会自动假设您在开发一个web应用程序并添加相应的spring配置,会自动去maven中读取每个starter中的spring.factories文件,该文件里配置了所有需要被创建spring容器中bean 2、在main方法中加上@SpringBootApplication和@EnableAutoConfiguration SpringBoot starter工作原理: 1、SpringBoot在启动时扫描项目依赖的jar包,寻找包含spring.factories文件的jar 2、根据spring.factories配置加载AutoConfigure 3、根据@Conditional注解的条件,进行自动配置并将bean注入到Spring Context SpringBoot的优点: 1、减少开发、测试时间和努力 2、使用JavaConfig有助于避免使用XML 3、避免大量的maven导入和各种版本冲突 4、提供意见发展方法 5、通过提供默认值快速开始开发 6、没有单独的web服务器需要,这就意味着不再需要启动Tomcat、Glassfish或其他任何东西 7、需要更少的配置,因为没有web.xml文件。只需添加用@Configuration注释的类,然后添加用@Bean注释的方法,Spring将自动加载对象并像以前一样对其进行管理。甚至可以将@Autowired添加到bean方法中,以使用Spring自动装入需要的依赖关系中 Springcloud解决那些问题: 配置管理、(注册中心eureka、zk)、服务发现、服务注册、断路器、路由策略、全局锁、分布式会话、客户端调用、接口网关(zuul)、服务管理系统 SpringBoot与Springcloud: 1>、SpringBoot简化了xml配置,快速整合框架 2>、Springcloud是一套微服务解决方案—RPC远程调用 3>、关系Springcloud依赖与SpringBoot(web组件用的SpringMVC),为什么Springcloud会依赖与SpringBoot?因为Springcloud写接口就是SpringMVC接口 4>、SpringBootproperties和yml中可以使用${random}设置一些随机值 服务的调用: rest、feign(均使用httpclient技术),负载均衡ribbon 服务调用的原理: 服务首先注册到注册中心eureka中(注册一个名字通过名字调用) 负载均衡 ribbon,先去注册中心取到对应的服务,然后交给我ribbon 配置详解: 1>、eureka.client.register-with-eureka:是否向注册中心注册自己,注册为true反之为false 2>、eureka.client.fetch-registry: 是否需要去检索服务,检索为true反之为false 3>、eureka.client.serviceUrl.defaultZone : 指定服务注册中心的地址 Eureka: 1>、eureka可分为三个角色:服务发现者、服务注册者、注册发现中心,但是这三个角色并不和实际部署的模型是一对一的关系 2>、所有的网络通信都是基于http(s)协议的 3>、Eureka和AWS是紧密结合的,无论是配置还是源码,比如Region、zone…,Region可以通过
全栈程序员站长
2022/09/07
2800
微服务 面试
1、什么是微服务?     就目前而言,对于微服务业界并没有一个统一的,标准的定义。
庞小明
2018/08/01
5900
相关推荐
SpringCloud常见面试题及答案
更多 >
LV.3
这个人很懒,什么都没有留下~
目录
  • 介绍
  • 先决条件
  • 第1步 - 配置项目
  • 第2步 - 导入MNIST数据集
  • 第3步 - 定义神经网络架构
  • 第4步 - 构建TensorFlow图
  • 第5步 - 培训和测试
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档