• [问题求助] OBS怎么共享部分文件的只读权限给别人?
    OBS怎么共享部分文件的只读权限给别人?
  • [问题求助] 上传图片和下载图片
    上传大量的商品图片是属于文件上传还是流式上传,或者是基于表单上传图片下载是选择流式下载还是对象下载这些接口的maven依赖在哪里获取?
  • [问题求助] OBS图片瘦身功能是基于什么原理实现的?是压缩宽高吗?
    OBS图片瘦身功能是基于什么原理实现的?是压缩宽高吗?
  • [问题求助] OBS 有提供给视频加水印的功能吗?
    OBS 有提供给视频加水印的功能吗?
  • [问题求助] 通过OBS剪切图片的时候如果,设置的宽度和高度超过了图片的宽高,是不是就不会剪切,还是会留白边?
     通过OBS剪切图片的时候如果,设置的宽度和高度超过了图片的宽高,是不是就不会剪切,还是会留白边?
  • [问题求助] 从相机拍摄的图片含有相机信息,OBS能否无损的保留这些信息?并提供查询接口直接能查询到这些数据?
  • [问题求助] 上传到OBS的图片,能作为html页面的img元素的src直接展示吗?
  • [问题求助] OBS Browser+、obsutil、obsfs,这3个工具有啥区别?
  • [问题求助] obs查看任务信息,发现中文乱码
    问题来源】【必填】    【南海农商行】【问题简要】【必填】 ICD V300R008C25 数据库接口方式,通过“取外呼任务接口”,获取到任务数据后,在“系统监控台”查看obs任务信息,发现中文乱码。【问题类别】【必填】    【可选问题分类:ICD obs 中文乱码】【AICC解决方案版本】【必填】    【AICC可选择版本:AICC 22.100】    【UAP可选择版本:V100R005】    【CTI可选择版本:ICD V300R008C25SPC012】【期望解决时间】【选填】尽快【问题现象描述】【必填】本地数据的字符集是utf8在“Web配置台”中的数据源中,配置连接字符串为:ip:3306@work3?CharacterEncodingName:UTF8获取到任务数据后,在“系统控制台”查看任务数据发现中文乱码:尝试过:1、将连接字符串为:ip:3306@work3?CharacterEncodingName:GBK        结果是存在中文乱码2、创建新的数据库,数据库字符设置为GBK,且将连接字符串为:ip:3306@work3?CharacterEncodingName:GBK       结果也是存在一样的中文乱码。所以,发帖请教老师们一下,可以检查哪里的配置来解决这个问题?
  • [问题求助] nodejs断点续传下载报错:TypeError:Cannot read properties of undefined (reading 'bufMD5) at calculateDownloadCheckpointMD5
    请教各位大佬:obsClient.downloadFile({ Bucket : '*******', Key : ******, DownloadFile : saveUrl, PartSize : 10 * 1024 * 1024, EnableCheckpoint : true, ProgressCallback: (transferredAmount, totalAmount, totalSeconds)=>{ let speed = transferredAmount * 1.0 / totalSeconds / 1024; let number = parseInt((transferredAmount * 100.0 / totalAmount)+'') mainWin.setProgressBar(number) } }, (err, result) => { if(err){ console.error('Error-->' + err); }else{ console.log('RequestId-->' + result.InterfaceResult.RequestId); console.log('LastModified-->' + result.InterfaceResult.LastModified); console.log('Metadata-->' + JSON.stringify(result.InterfaceResult.Metadata)); } });
  • [问题求助] obs的maven依赖问题
    请问 引用java的sdk是使用哪个合适?为啥有2个obs的库呢?<dependency> <groupId>com.huaweicloud</groupId> <artifactId>esdk-obs-java</artifactId> </dependency> <dependency> <groupId>com.huaweicloud.sdk</groupId> <artifactId>huaweicloud-sdk-obs</artifactId> </dependency>
  • [问题求助] modelbox如何支持单卡多实例?
    显卡的显存比较大,但发现提升batch size并不会明显改善吞吐量。想问下modelbox能否支持单卡多实例,也就是在一张卡上面将一个推理模型部署多次?
  • [技术干货] 【FAQ】存储服务12月问题集合
    1. OBS怎么进行备份和灾难恢复链接地址:cid:link_2OBS通过如下方式实现备份和容灾:创建桶时开启多AZ属性,用户数据冗余存储至多个AZ中。 通过跨区复制功能。用户可以将一个区域的桶中数据复制到另一个区域,实现云端备份。 将OBS中的数据下载到本地,本地备份数据。 cid:link_14OBS通过如下方式实现备份和容灾:创建桶时开启多AZ属性,用户数据冗余存储至多个AZ中。 通过跨区复制功能。用户可以将一个区域的桶中数据复制到另一个区域,实现云端备份。 将OBS中的数据下载到本地,本地备份数据。2. OBS的实现原理是什么,为什么不用数据库存储链接地址:cid:link_3对象存储的实现原理:分布式架构: OBS通常基于分布式架构,数据被分布存储在多个物理节点上。这使得OBS能够横向扩展,处理大规模的数据,同时具备高可用性和容错性。 数据冗余和容错: 对象存储通常会在多个节点上存储数据的冗余副本,以防止单个节点故障。这样,即使某个节点失效,数据仍然可用。 为什么不使用传统数据库:大规模数据: 传统数据库通常更适用于结构化数据的存储和检索,而OBS更专注于大规模非结构化数据。对于海量的图片、视频等二进制文件,传统数据库可能会面临性能和扩展性的限制。 对象存储的简单性: OBS的设计更为简单,专注于提供高效的对象存储服务。相对于复杂的关系型数据库,对象存储更注重在大规模场景下的数据分布和访问效率。 成本考虑: 对象存储通常提供较低的存储成本,适用于需要大规模存储的场景。传统数据库可能会在处理大量非结构化数据时变得昂贵和不切实际。 特性和用途的不同:面向不同用途: 传统数据库更适用于支持复杂的事务和查询操作,而对象存储更适用于快速的、分布式的文件访问。 RESTful接口: OBS通常提供RESTful接口,使得开发者能够轻松地集成和使用存储服务。这种简单而标准的接口有助于各种应用对大规模数据进行访问。3. 如果一个用户在下载OBS的某个文件,同时另一个用户开始修改那个文件,那么下载的用户会下载失败吗链接地址:cid:link_4这个得先明确具体的操作场景:桶的类型是对象桶还是POSIX桶?对象桶是没有修改操作的,只有重新上传同名文件会覆盖原对象4. OBS的SDK在下载之前会判断本地剩余空间吗?如果剩余空间小于文件大小就不下载链接地址:cid:link_5是的,会报错内存或磁盘空间不足5. 使用OBS下载文件时,如果下载到一半中断了,OBS下载的文件占用空间是文件总大小,还是下载多少占多少链接地址:cid:link_6会锁定整个文件的大小。6. OBS在上传和下载对象时,是否有对数据进行加密链接地址:cid:link_7服务端加密示例:cid:link_11客户端加密:cid:link_07. OBS上传同一个文件(即之前已经上传过了)是否还会重新上传链接地址:cid:link_8华为云OBS上传同一个文件(即之前已经上传过了)不会重新上传。当您上传一个已经存在的文件时,华为云OBS会根据文件的ETag(文件特征值,由文件的内容计算得出)来判断文件是否已经上传过。如果文件的ETag已经存在,OBS会认为文件已经上传过,并返回该文件已经存在的状态。而如果文件的ETag不存在,则说明文件之前并未上传成功或文件在上传过程中出现了变化,这时OBS会重新上传该文件。如果桶开启多版本控制,则会重新上传生成一个带最新版本标记的同名对象8. OBS和传统的FTP比起来咋样,为啥OBS能取代FTP链接地址:cid:link_1数据稳定,业务可靠:OBS支撑华为手机云相册,数亿用户访问,稳定可靠。通过跨区域复制、AZ之间数据容灾、AZ内设备和数据冗余、存储介质的慢盘/坏道检测等技术方案,保障数据持久性高达99.9999999999%,业务连续性高达99.995%,远高于传统架构。多重防护,授权管理:OBS通过可信云认证,让数据安全放心。支持多版本控制、敏感操作保护、服务端加密、防盗链、VPC网络隔离、访问日志审计以及细粒度的权限控制,保障数据安全可信。 千亿对象,千万并发:OBS通过智能调度和响应,优化数据访问路径,并结合事件通知、传输加速、大数据垂直优化等,为各场景下用户的千亿对象提供千万级并发、超高带宽、稳定低时延的数据访问体验。 简单易用,便于管理:OBS支持标准REST API、多版本SDK和数据迁移工具,让业务快速上云。无需事先规划存储容量,存储资源和性能可线性无限扩展,不用担心存储资源扩容、缩容问题。OBS支持在线升级、在线扩容,升级扩容由华为云实施,客户无感知。同时提供全新的POSIX语言系统,应用接入更简便。 数据分层,按需使用:提供按量计费和包年包月两种支付方式,支持标准、低频访问、归档数据、深度归档数据(受限公测)独立计量计费,降低存储成本。9. OBS上传错误的错误码有哪些,文档链接有吗链接地址:cid:link_9参考此链接:cid:link_13 (内部公开)10. 华为云的OBS和传统的将数据存储在数据库有什么不同链接地址:cid:link_10cid:link_12 产品优势
  • [技术干货] Mnist手写数字分类实验
    一、实验目的搭建机器学习环境创建模型,补充并调通给定的Mnist分类代码创建算法并提高准确率二、实验内容与实验步骤环境搭建数据预处理模型建立与训练模型评估​ 这次的代码实验数据预处理、模型评估部分均已提供代码,我们只需要实现环境搭建以及模型建立与训练。在模型建立时我选择CNN模型以及adam优化器,并进行了参数的调整以提高准确性,具体的调整过程,我会在第五部分实验结果与总结中提出。三、实验环境华为云ModelArts64位电脑四、实验过程与分析环境搭建  创建OBS桶按照pdf进行对应配置,接着新建文件夹MINST并上传代码文件与数据文件。​ 按照pdf的教程创建算法并创造训练集,pdf上训练输入的参数有一点问题,应该选择到数据集所在的目录而不是选择到数据集.​ 均完成后就可以开启训练任务了。下面开始分析本次实验的代码以及调参的过程。数据预处理  在头文件配置TensorFlow和Keras运行环境,以便后续进行神经网络的训练。数据集导入部分需要在源代码基础上修改,不然会出现报错,使用moxing复制数据集到工作目录,然后提取其中的数据和标签,到这里我们的训练数据已经准备完毕。接着进行预处理,使用Keras扩展图像数据的维度,把像素值缩放保存,把标签转换为one-hot编码。import os import numpy as np import tensorflow as tf import argparse from tensorflow.keras import backend as K from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Conv2D from tensorflow.keras.layers import Dropout, MaxPooling2D, Flatten from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical import moxing # 参数解析,用于在modelArt中读取MNIST数据集 parser = argparse.ArgumentParser() parser.add_argument('--data_url', required=True, default=None, help='test') arg = parser.parse_args() # src_url为OBS桶中数据集的路径,dst_url为执行容器中的路径,两者皆为目录,用于访问OBS中的数据 moxing.file.copy_parallel(src_url=os.path.join(arg.data_url, 'mnist.npz'), dst_url='mnist.npz') seed = 7 np.random.seed(seed) # 加载MNIST数据集 dateset_path =os.path.join(arg.data_url, 'mnist.npz') f = np.load(dateset_path) X_train, y_train = f['x_train'], f['y_train'] X_test, y_test = f['x_test'], f['y_test'] # 数据预处理 X_train = K.expand_dims(X_train, -1) X_test = K.expand_dims(X_test, -1) X_train = X_train / 255 X_test = X_test / 255 # 将标签转换为one-hot编码 y_train = tf.convert_to_tensor(to_categorical(y_train)) y_test = tf.convert_to_tensor(to_categorical(y_test)) num_classes = y_test.shape[1]模型建立与训练​ 创建一个序贯模型,表示按顺序堆叠的神经网络层。接着,通过添加卷积层和池化层,提取图像特征。第一个卷积层包含32个滤波器,每个滤波器的大小为(3, 3),使用ReLU激活函数。接着是一个最大池化层,用于降低空间维度。然后,再次添加一个卷积层和最大池化层,但这次使用64个滤波器。接下来,通过展平操作将多维数据展平为一维,为连接到全连接层做准备。​ 在全连接部分,首先添加了一个具有128个神经元的全连接层,使用ReLU激活函数。为了防止过拟合,添加了一个Dropout层,丢弃率为0.5。通过一个包含10个神经元的输出层进行多类别分类,使用softmax激活函数。最后,通过model.compile()编译模型,指定了损失函数、优化器(Adam)以及准确度。# 使用Keras定义卷积神经网络 def build_model(lr): # 创建一个序贯模型 model = Sequential() # 添加卷积层和池化层 model.add(Conv2D(filters=32, kernel_size=(3, 3),input_shape=(28, 28, 1),activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(filters=64, kernel_size=(3, 3),activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) # 展平操作 model.add(Flatten()) # 全连接层 model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) # 输出层 model.add(Dense(10, activation='softmax')) # 打印模型概要信息 model.summary() # 编译模型,指定损失函数、优化器和评估指标 model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) return model模型评估​ 这段代码没有作修改,作用是通过测试集评估已经训练好的卷积神经网络模型的性能,最终获得的准确度为0.9523,接下来来到最爱的调参环节。# 评估模型性能 scores = model.evaluate(X_test, y_test, verbose=0) loss, accuracy = model.evaluate(X_test, y_test, verbose=1) print('loss:%.4f accuracy:%.4f' %(loss, accuracy)) print("Baseline Error: %.2f%%" % (100 - scores[1] * 100)) ## 五、实验结果与总结 ​ 我们主要修改的就是模型建立与训练部分的代码,调整不同的参数以获得更高的准确性(但是还要防止过拟合),目前获得的准确度是0.9523. #### 学习率调参 ​ 我们可以先放大学习率来寻找一个准确性较高的学习率范围,于是调为比较大的0.01查看效果,发现正确率提高到96.88%。这时不断缩小学习率,发现准确性不断提高,直到0.03时准确率降低,所以当学习率在0.004时,学习率基本最高。 ```python # 使用 Adam 优化器和指定学习率,依次测试0.01 0.007 0.005 0.003 0.004 # model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.01), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.007), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.005), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.003), metrics=['accuracy']) model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.004), metrics=['accuracy']) return modelbatch_size调参​ 我们把batch_size从200调到300看看效果,发现准确性从0.9776提高到0.9791,略微提高了一点,我们可以先尝试一下其他调参。# batch_size调参,尝试200 300 # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=200, verbose=2, steps_per_epoch=1) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=300, verbose=2, steps_per_epoch=1)epochs调参​ 增加迭代次数,随着epochs不断增加,准确性也在不断提高,但是为了防止过拟合,我们调到300,此时基本已经达到最大的准确率0.9876。暂时这就是最终的结果。# epochs调参,尝试100 200 300 # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=300, verbose=2, steps_per_epoch=1) # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=200, batch_size=300, verbose=2, steps_per_epoch=1) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=300, batch_size=300, verbose=2, steps_per_epoch=1)steps_per_epoch调参​ 在查找资料的时候发现,steps_per_epoch也会对结果有影响,于是跟着教程调整为了None,接着发现准确度终于突破了99大关达到了0.9915,至此我们的调参结束。# model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=300, batch_size=300, verbose=2, steps_per_epoch=1) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=300, batch_size=300, verbose=2, steps_per_epoch=None)六、附录​ 以下为源代码,注释部分为每次测试的参数,未注释为最终调整的版本。import os import numpy as np import tensorflow as tf import argparse from tensorflow.keras import backend as K from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Conv2D from tensorflow.keras.layers import Dropout, MaxPooling2D, Flatten from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical import moxing # 参数解析,用于在modelArt中读取MNIST数据集 parser = argparse.ArgumentParser() parser.add_argument('--data_url', required=True, default=None, help='test') arg = parser.parse_args() # src_url为OBS桶中数据集的路径,dst_url为执行容器中的路径,两者皆为目录,用于访问OBS中的数据 moxing.file.copy_parallel(src_url=os.path.join(arg.data_url, 'mnist.npz'), dst_url='mnist.npz') seed = 7 np.random.seed(seed) # 加载MNIST数据集 dateset_path =os.path.join(arg.data_url, 'mnist.npz') f = np.load(dateset_path) X_train, y_train = f['x_train'], f['y_train'] X_test, y_test = f['x_test'], f['y_test'] # 数据预处理 X_train = K.expand_dims(X_train, -1) X_test = K.expand_dims(X_test, -1) X_train = X_train / 255 X_test = X_test / 255 # 将标签转换为one-hot编码 y_train = tf.convert_to_tensor(to_categorical(y_train)) y_test = tf.convert_to_tensor(to_categorical(y_test)) num_classes = y_test.shape[1] # 使用Keras定义卷积神经网络 def build_model(lr): # 创建一个序贯模型 model = Sequential() # 添加卷积层和池化层 model.add(Conv2D(filters=32, kernel_size=(3, 3), input_shape=(28, 28, 1), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(filters=64, kernel_size=(3, 3), activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) # 展平操作 model.add(Flatten()) # 全连接层 model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) # 输出层 model.add(Dense(10, activation='softmax')) # 打印模型概要信息 model.summary() # 编译模型,指定损失函数、优化器和评估指标 # model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.01), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.007), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.005), metrics=['accuracy']) # model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.003), metrics=['accuracy']) model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.004), metrics=['accuracy']) return model # 构建模型 model = build_model(lr=1) # 训练模型 # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=200, verbose=2, steps_per_epoch=1) # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=300, verbose=2, steps_per_epoch=1) # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=100, batch_size=300, verbose=2, steps_per_epoch=1) # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=200, batch_size=300, verbose=2, steps_per_epoch=1) # model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=300, batch_size=300, verbose=2, steps_per_epoch=1) model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=300, batch_size=300, verbose=2, steps_per_epoch=None) # 评估模型性能 scores = model.evaluate(X_test, y_test, verbose=0) loss, accuracy = model.evaluate(X_test, y_test, verbose=1) print('loss:%.4f accuracy:%.4f' %(loss, accuracy)) print("Baseline Error: %.2f%%" % (100 - scores[1] * 100))
  • [技术干货] 基于MindSpore的鸢尾花分类
    一、实验目的了解逻辑回归的基本概念以及如何使用MindSpore进行逻辑回归实验基于两个种类的鸢尾花数据,使用 MindSpore 进行逻辑回归实验,分析自变量和因变量(概率)之间的关系,求得一个概率函数,即实现鸢尾花的二分类预测二、实验内容与实验步骤环境搭建数据准备数据预处理模型建立与训练模型评估  这是一个完整的实验步骤,我们首先根据手册实现基础实验——鸢尾花二分类预测,接着学习这种思路来尝试实现创新设计——鸢尾花多分类预测。三、实验环境华为云ModelArtsMindSpore 1.364位电脑四、实验过程与分析环境搭建  进入ModelArts,进入控制台,点击开发环境中的Notebook进行创建,按手册进行配置后打开Notebook,选择右侧“MindSpore-python3.7-aarch64”按钮,进入Notebook环境,于是我们可以开始运行目标代码。数据准备  在官网下载Iris数据集(因为莫名Iris 数据集官网和华为云 OBS的链接都是404),下载数据iris.data并上传到实验环境中。 数据预处理  在头文件配置MindSpore的运行环境,包括运行模式和目标设备,以便后续进行神经网络的训练或推理操作,接着打开导入的Iris数据集并查看部分数据。  定义一个标签映射字典,加载鸢尾花数据并将特征和标签存储在NumPy数组中。使用matplotlib库进行 2 维可视化,分别表示鸢尾花的两个类别(Iris-setosa和Iris-versicolor)的花萼长度与宽度之间的关系,以便通过可视化来观察数据分布。可以看出这两类样本是线性可分的。  将数据集分成训练集和测试集(比例为8:2),同时创建了适合神经网络训练的数据集对象 ds_train,用于后续的模型训练操作。模型建立与训练  我们使用的联系函数是Sigmoid函数,简单的绘制了一个图像。  下面是模型建立与训练的过程:定义了一个经验风险函数函数 Loss,继承自MindSpore的nn.Cell类。这个损失函数使用Sigmoid交叉熵损失来衡量模型输出与实际标签之间的差异,然后计算均值。创建一个神经网络模型 net,该模型包含一个全连接层,用于进行二元分类。输入维度为4,输出维度为1。实例化损失函数对象 loss,并创建了一个随机梯度下降(SGD)优化器 opt。模型评估  使用已训练的神经网络模型进行测试,并计算模型的测试准确度,测试集上的准确率达到了 1.0 左右,所以模型学会了区分2类鸢尾花。五、创新设计  该部分主要参考手册的思路以及csdn,因为能力有限无法完全独立实现。跳过环境配置与数据准备,直接从数据预处理开始。数据预准备  首先打开导入的Iris数据集,将特征数据和标签数据分别存储到 data_x和 data_y 中,接下载划分测试基于训练集(比例依然为8:2),测试集有30个数据。  接着将鸢尾花数据集的标签进行one-hot编码,将其从原始的数字编码转换为与类别数量相等的二进制编码,以便用于多类别分类任务,编码后的格式如下。 模型建立与训练  我们使用的是Softmax激活函数,输入特征经过权重的加权和指数化后,通过 softmax 函数得到每个类别的概率估计。  定义损失函数和梯度下降函数,遍历每个样本计算交叉熵损失并累加计算平均损失,通过计算每个样本的梯度获得平均梯度,后续用于权重w的更新。  接下来是模型训练的过程,使用全批量梯度下降法来更新模型的权重,并在每个训练迭代中计算并记录测试集和训练集上的准确度和损失。通过迭代的方式,监测模型的性能并输出当前的训练进展。最终返回了更新后的权重以及记录的性能指标,包括测试准确度、训练准确度、测试损失和训练损失。  初始化权重参数,开始训练模型。模型评估  定义accuracy函数,计算测试机的正确率。   训练完模型之后,查看输出的结果,并输出二维图像。​ 可以看出随着epoch变多,accuracy不断变大很快为1,train loss和test loss不断减小,train accuracy不断提高稳定在0.975,基本能实现三分类准确。