前言
之前强化学习的课程老师鼓励参加华为云的比赛,慧科杯第一届人工智能应用创新大赛(又想去白嫖GPU的资源)首先大概说一下这个比赛,基于华为ModelArts平台,和之前学习的百度的AI studio 来说,最大的不同就是华为的notebook环境配置了tf(1.13)和pytorch的基本环境,可以说更加方便,在直播的答疑课上顺带学了学桶的机制,包括上传大规模文件的做法等等,收获还是挺多。这里只介绍我在这个平台想学的一部分东西。
参加的比赛内容简介
因为老师比较要求的是用强化学习去做,再加上前段时间比较忙,这里将我做的关于这次比赛的ppt在这分享一下,提前说一下,由于组员和时间安排的问题,比赛没有继续参加。
该实验主要是参考如下论文:
由于各种原因吧,包括分工等问题,也有自己的问题,比赛没能继续,但这其中包括对MIMIC医用数据集的处理过程让我将SQL的学习提上日程,关于深度强化学习和DQN等相关有机会再做整理。现在步入正题,慧科的网站留下了一系列比较好的课程,这里对课程的学习做一总结。
深度学习部分 基础+CV+NLP
这里的老师是开课吧的同济子豪兄的张子豪主讲,我更推荐大家去他的b站跟这门课的讲解:
链接: 【子豪兄】精讲CS231N斯坦福计算机视觉公开课(2020最新).我全程跟下来最大的收获就是非常仔细,然后up借用自己收集的斯坦福的课程可视化实例讲解代码,还是非常直接和易懂的。
模型应用之FLASK
这个是我之前没有学过的,所以我跟着主讲老师的节奏一步步的学习:
安装与测试flask
安装成功:
备注:这里我用的是python3.6 (老师用的是3.7,但3.6应该也可以用)tensorflow 1.13.1gpu的版本,conda 10.0 开发IDE pycharm
新建一个flask项目,并指定解释器:
直接点右键运行得到的网址并打开 :
网站寻址的过程可简述为:网址首先是找DNS的服务器,网址到IP的转换,返回一个IP地址,再经过路由器找到一台服务器,服务器上运行着web实例。HTTPS默认端口是443 (网络层用TCP),三次握手保证安全传输。
这里非常推荐之前刷到的一个宝藏视屏
: 【毕设必备】手把手带你用Python搭建一个简单的后端服务(1)- API的创建,前后端交互的数据传递,GET,POST,JSON,FLASK.
讲的非常清楚
get:获取主页信息,request到服务器,服务器处理并返回一个reponse .。浏览器应答接受到主页的信息。浏览器就会去渲染html的信息内容对应的标签,文字啊图片啊,但这只是个静态页面,可以用css去提升样式(jquery是css的超集)
这里记载几个小技巧:
1.ctrl+f5 清空缓存的刷新
2. 在程序中不中断执行会有好几个程序会执行,会占用端口,有可能导致网页不知道调用哪个实例
3. html里调变量是用大括号
4. host='0.0.0.0’代表任何别的主机可以访问我的flask(除去防火墙)
5. C:\Users\Administrator>ipconfig -all 查看本机ip地址(IPv4 地址)
6. pycharm会有些缓存问题,所以可在python的解释器里运行,当然也可以通过技巧1清除缓存后刷新。
7.debug在1.0后的版本可在pycharm里直接设置:但要保证只有一个实例,勾选DEBUG,apply
8.flask解析地址用路由去做的,即@app.route (’/’)#根目录下执行或者自己设置的目录格式
9.submit会把form里的所有东西上传到网址
10.脚本信息在html里要放到head里
11.heml所得标签都在document里
12 写结构体def uploadImag():的时候可以先用pass占用一下,要不会报错
前端上传 后端处理,再将结果上传到前端
首先,老师的演示是POST模式下的图片从前端上传到后端本机的过程,具体代码如下:
@app.route('/uploadImg',methods=['GET','POST'])
def uploadImag():
if request.method=="GET":
resw = make_response (render_template ('index.html')) # 如果是路由请求是GET,则直接返回网页
return resw
elif request.method=="POST":
if 'myImg' in request.files:
objFile = request.files.get('myImg')
strFileName = objFile.filename
strFilepath="./static/myImage/"+strFileName #组合路径
objFile.save(strFilepath)
return "file save successed"
else:
err = 'error'
return err
else:
err= 'error'
return err
index.html文件中编写的head和body程序如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function showImg(file){
var reader = new FileReader();
reader.onload = function (evt) {
<!--图片onload(载入完毕)的时候触发function,其功能是获取图片的id来获取元素,再用src动态指定-->
document.getElementById('myImgxx').src = evt.target.result;
}
reader.readAsDataURL(file.files[0]) <!--之前是reader有文件载入的时候指定的标签是哪个,现在是指定传入参数的具体哪个对象 -->
}
</script>
</head>
<body>
<img id="myImgxx">
<form method="post" action="/uploadImg" enctype="multipart/form-data">
<input type="file" name="myImg" onchange="showImg(this)"><br><br>
<input type="submit" value="上传图片">
</form>
</body>
</html>
在程序中加了一些限制的条件判断,其中的注释写的非常清楚,运行flask的结果如下
上传后的结果,然后再本机的./static/myImage文件夹下可以找到该图片,为了避免重复,还可以加上时间戳用于区分
然后老师在后端编写了一份图像分类基于resnet50的分类模型,并调用这个模型的参数,然后返回给前端一个类别名字(分类50种狗)
from flask import Flask,make_response,render_template,request
from keras import models
from keras.preprocessing import image
import numpy as np
from keras.backend import set_session
import tensorflow as tf
sess = tf.Session()
set_session(sess)
grah = tf.get_default_graph()
print("model loading")
myModel = models.load_model("./static/model/DogKinds_ResNeXt50.hdf5")#预训练模型,有点大
print("model loaded")
global dictClasses #建立一个全局对象
with open('./static/model/trainClasses.txt') as f: #类别的字典,前类型后数字
dictClasses = eval(f.read())
app = Flask (__name__)
@app.route ('/')#根目录下执行
def hello_world():
myname = 'abc'
myage = 21
# y = 0 #测试debug
# x = myage / 0
myList = range(0,10)
resw = make_response(render_template('index.html', mname = myname,mage = myage,mList=myList)) #服务器处理,返回给网站一个结果,内容定位到templates里的index.html文件
return resw
@app.route ('/hello') #根目录+hello下执行
def my_hello():
Mystr = 'my hello'
return Mystr
@app.route('/uploadImg',methods=['GET','POST'])
def uploadImag():
if request.method=="GET":
resw = make_response (render_template ('index.html')) # 如果是路由请求是GET,则直接返回网页
return resw
elif request.method=="POST":
if 'myImg' in request.files:
objFile = request.files.get('myImg')
strFileName = objFile.filename
strFilepath="./static/myImage/"+strFileName #组合路径
objFile.save(strFilepath)
objImg = image.load_img (strFilePath, target_size=(150, 150)) #读入图像
xImg = image.img_to_array (objImg) #将图片转换为数组
yImg = xImg.astype ("float32") / 255 #归一化处理
zImg = np.expand_dims (yImg, axis=0)#数据输入需要批量操作,只不过每次批量只有一个数据而已
with grah.as_default ( ):
set_session (sess)
res = myModel.predict_classes (zImg)
print (res) #返回的是一个数字,要和txt文件里去匹配
for k, v in dictClasses.items ( ):
if v == res:
return k
return "file save successed"
else:
err = 'error'
return err
else:
err= 'error'
return err
if __name__ == '__main__':
app.run ()
非常值得注意的两点是:
1.在开始时,老师没有加grah = tf.get_default_graph()的模式运行报错,老师给出的解释是运行flask处理每一个request会开启一个线程去执行,建立的全局模型需要一个图去操作:
from keras.backend import set_session
import tensorflow as tf
sess = tf.Session()
set_session(sess)
grah = tf.get_default_graph()
运用modle的时候在使用默认的图和绘画,再去预测:
with grah.as_default ( ):
set_session (sess)
res = myModel.predict_classes (zImg)
print (res) #返回的是一个数字,要和txt文件里去匹配
2.根据文件里的字典去查询具体的类别时,用item()读取所有数据,并且可以建立一个全局的对象,原因是类别是不变的,方便其他程序去调
global dictClasses #建立一个全局对象
with open('./static/model/trainClasses.txt') as f: #类别的字典,前类型后数字
dictClasses = eval(f.read())
最终网站前端的结果如图所示:
小结:老师在视屏中也说了,这些只是一个网站的基本流程,包括渲染啊,ccs这些也不是一天两天讲的完,所以只适合入门培训
套用已有的网站模板
老师推荐的是在模板之家这个网站:http://www.cssmoban.com/cssthemes/
这里现将文件夹放置在外面,即一个错的路径:
原因是要想用flask的路由去访问 res = make_response(render_template(‘index.html’))即template路径下的索引,就得将下载的index放到template文件夹下,注意index文件唯一,把其余的广告类似的可以删了,然后拖动并勾选,目的是利用pycharm强大的功能区把原先文件下用到’新index’的路径统统改到复制的红框,见下图,目录下,这样就不用一个个改了
接着再把剩余的文件直接拖到stactic文件夹下:本来其余的html要用@app.route路由的方式访问,pychaem依然会帮我们修改对应路径
再次启动app运行,会加载下好的模板,并且可以切换,然后再把自己的功能部署上。