提交 d8811fc0 编写于 作者: W wizardforcel

2021-01-06 17:11:01

上级 d41f03d7
......@@ -327,7 +327,7 @@ for imgid in train:
max_caption_len = max(max_caption_len, len(caption.split())+1)
```
3. 我们将使用 Keras 模型资源库中的`ResNet50`预训练模型。 我们将输入形状设置为 224 x 224 x 3,其中`224 x 244`是将传递给模型的每个图像的尺寸,而 3 是颜色通道的数量。 请注意,与**美国国家混合标准技术研究院****MNIST**)数据集不同,在该数据集中每个图像的尺寸均相等,而 Flickr8k 数据集则并非如此。 该代码可以在以下代码段中看到:
3. 我们将使用 Keras 模型资源库中的`ResNet50`预训练模型。 我们将输入形状设置为`224 x 224 x 3`,其中`224 x 244`是将传递给模型的每个图像的尺寸,而 3 是颜色通道的数量。 请注意,与**美国国家混合标准技术研究院****MNIST**)数据集不同,在该数据集中每个图像的尺寸均相等,而 Flickr8k 数据集则并非如此。 该代码可以在以下代码段中看到:
```py
model = ResNet50(weights="imagenet", input_shape=(224,224,3))
......@@ -665,11 +665,11 @@ plt.show()
# 了解相机插件
通过`camera`依赖项提供的 Camera 插件,使我们可以自由访问设备的摄像机。 它为 Android 和 iOS 设备提供支持。 该插件是开源的,并托管在 GitHub 上,因此任何人都可以自由访问代码,修复错误并提出对当前版本的增强建议。
通过`camera`依赖项提供的相机插件,使我们可以自由访问设备的摄像机。 它为 Android 和 iOS 设备提供支持。 该插件是开源的,并托管在 GitHub 上,因此任何人都可以自由访问代码,修复错误并提出对当前版本的增强建议。
该插件可用于在小部件上显示实时摄像机预览,捕获图像并将其本地存储在设备上。 它也可以用来录制视频。 此外,它具有访问图像流的功能。
可以通过以下三个简单步骤将 Camera 插件添加到任何应用程序:
可以通过以下三个简单步骤将相机插件添加到任何应用程序:
1. 安装包装
2. 添加用于持久存储和正确执行的方法
......@@ -879,7 +879,7 @@ capturePictures() async {
}
```
在前面的代码片段中,我们首先使用`DateTime.now().millisecondsSinceEpoch()`找出当前时间(以毫秒为单位),然后将其转换为字符串并将其存储在变量 timestamp 中。 时间戳将用于为我们将进一步存储的图像文件提供唯一的名称。 接下来,我们使用`getApplicationDocumentsDirectory()`获取可用于存储图像的目录的路径,并将其存储在`Directory`类型的`extDir`中。 现在,我们通过在外部目录后附加`'/Pictures/generate_caption_images'`来创建适当的目录路径。 然后,我们通过将目录路径与当前时间戳组合并为其指定`.jpg`格式来创建最终的`filePath`。 由于时间戳始终具有不同的值,因此所有单击的图像的`filePath`将始终是唯一的。 最后,我们使用当前的相机控制器实例调用`takePicture()`并传入`filePath`来捕获图像。 我们存储在`imgFile`中创建的图像文件,稍后将用于生成适当的字幕。
在前面的代码片段中,我们首先使用`DateTime.now().millisecondsSinceEpoch()`找出当前时间(以毫秒为单位),然后将其转换为字符串并将其存储在变量`timestamp`中。 时间戳将用于为我们将进一步存储的图像文件提供唯一的名称。 接下来,我们使用`getApplicationDocumentsDirectory()`获取可用于存储图像的目录的路径,并将其存储在`Directory`类型的`extDir`中。 现在,我们通过在外部目录后附加`'/Pictures/generate_caption_images'`来创建适当的目录路径。 然后,我们通过将目录路径与当前时间戳组合并为其指定`.jpg`格式来创建最终的`filePath`。 由于时间戳始终具有不同的值,因此所有单击的图像的`filePath`将始终是唯一的。 最后,我们使用当前的相机控制器实例调用`takePicture()`并传入`filePath`来捕获图像。 我们存储在`imgFile`中创建的图像文件,稍后将用于生成适当的字幕。
12. 如前所述,为了从实时摄像机的提要中生成字幕,我们会定期捕获图像。 为了使它起作用,我们修改`initializeController()`并添加一个计时器,如下所示:
......@@ -953,7 +953,7 @@ Future<Map<String, dynamic>> fetchResponse(File image) async {
}
```
在上述方法中,我们首先通过查看文件的头字节来找到所选文件的 mime 类型。 然后,我们按照托管 API 的要求初始化一个多部分请求。 我们将传递给函数的文件附加为`image` post 参数。 由于`image_picker`存在一些错误,因此错误地将图像扩展名与文件名(例如`filenamejpeg`)混合在一起,因此我们在请求正文中明确传递了图像扩展名,这会在服务器端管理或验证文件扩展名时产生问题。 响应采用 JSON 格式,因此,我们需要使用`json.decode()`对其进行解码,并使用`res.body`传入响应的主体。 现在,我们通过调用下一步定义的`parseResponse()`来解析响应。 此外,我们使用`catchError()`检测并打印执行`POST`请求时可能发生的任何错误。
在上述方法中,我们首先通过查看文件的头字节来找到所选文件的 mime 类型。 然后,我们按照托管 API 的要求初始化一个多部分请求。 我们将传递给函数的文件附加为`image` POST 参数。 由于`image_picker`存在一些错误,因此错误地将图像扩展名与文件名(例如`filenamejpeg`)混合在一起,因此我们在请求正文中明确传递了图像扩展名,这会在服务器端管理或验证文件扩展名时产生问题。 响应采用 JSON 格式,因此,我们需要使用`json.decode()`对其进行解码,并使用`res.body`传入响应的主体。 现在,我们通过调用下一步定义的`parseResponse()`来解析响应。 此外,我们使用`catchError()`检测并打印执行`POST`请求时可能发生的任何错误。
4. 成功执行`POST`请求并从模型中获得带有传递的图像的标题的响应之后,我们在`parseResponse()`方法内部解析响应,如下所示:
......@@ -1080,6 +1080,6 @@ void main() => runApp(MyApp());
# 概要
在本章中,我们了解了如何创建一个应用,该应用使用深层的 CNN 和 LSTM 为摄像机的提要实时生成字幕。 我们还看到了如何快速将以 Docker 映像形式提供的某些机器学习/深度学习模型部署到 Red Hat OpenShift,并以可调用 API 的形式轻松获取它们。 从应用程序开发人员的角度来看,这是至关重要的,因为当与一组机器学习开发人员一起工作时,他们通常会为您提供要使用的模型的 Docker 映像,这样您就无需在其中执行任何代码或配置。 系统。 可以将这种应用程序用于多种用途,例如为盲人创建辅助技术,生成当时发生的事件的成绩单,或者(例如)为孩子提供现场指导,以帮助他们识别环境中的物体。 我们介绍了如何应用 Flutter Camera 插件并在框架上进行深度学习。
在本章中,我们了解了如何创建一个应用,该应用使用深层的 CNN 和 LSTM 为摄像机的提要实时生成字幕。 我们还看到了如何快速将以 Docker 映像形式提供的某些机器学习/深度学习模型部署到 Red Hat OpenShift,并以可调用 API 的形式轻松获取它们。 从应用程序开发人员的角度来看,这是至关重要的,因为当与一组机器学习开发人员一起工作时,他们通常会为您提供要使用的模型的 Docker 映像,这样您就无需在其中执行任何代码或配置。 系统。 可以将这种应用程序用于多种用途,例如为盲人创建辅助技术,生成当时发生的事件的成绩单,或者(例如)为孩子提供现场指导,以帮助他们识别环境中的物体。 我们介绍了如何应用 Flutter 相机插件并在框架上进行深度学习。
在下一章中,我们将研究如何开发用于执行应用程序安全性的深度学习模型。
\ No newline at end of file
......@@ -33,7 +33,7 @@
# 创建 UI
让我们从创建应用程序的登录屏幕开始。 **用户界面****UI**)将包含两个 TextFormField 来获取用户的电子邮件 ID 和密码,RaisedButton 进行注册/登录,以及 FlatButton 进行注册和登录之间的切换 在操作中。
让我们从创建应用程序的登录屏幕开始。 **用户界面****UI**)将包含两个`TextFormField`来获取用户的电子邮件 ID 和密码,`RaisedButton`进行注册/登录,以及`FlatButton`进行注册和登录之间的切换 在操作中。
以下屏幕快照标记了将用于应用程序的第一个屏幕的小部件:
......@@ -145,7 +145,7 @@ enum FormMode { SIGNIN, SIGNUP }
}
```
如果`_formMode`的当前值为 SIGNIN 并按下按钮,则应更改为 SIGNUP 并显示`Create an account`。 否则,如果`_formMode`将 SIGNUP 作为其当前值,并且按下按钮,则该值应切换为由文本`Have an account? Sign in`表示的 SIGNIN。 使用三元运算符创建`RaisedButton``Text`子级时,添加了在文本之间切换的逻辑。 `onPressed`属性使用非常相似的逻辑,该逻辑再次检查`_formMode`的值以在模式之间切换并使用`_switchFormToSignUp``_switchFormToSignin`方法更新`_formMode`的值。 我们将在“步骤 7”和`8`中定义`_switchFormToSignUp``_switchFormToSignin`方法。
如果`_formMode`的当前值为`SIGNIN`并按下按钮,则应更改为`SIGNUP`并显示`Create an account`。 否则,如果`_formMode``SIGNUP`作为其当前值,并且按下按钮,则该值应切换为由文本`Have an account? Sign in`表示的`SIGNIN`。 使用三元运算符创建`RaisedButton``Text`子级时,添加了在文本之间切换的逻辑。 `onPressed`属性使用非常相似的逻辑,该逻辑再次检查`_formMode`的值以在模式之间切换并使用`_switchFormToSignUp``_switchFormToSignin`方法更新`_formMode`的值。 我们将在“步骤 7”和 8 中定义`_switchFormToSignUp``_switchFormToSignin`方法。
7. 现在,我们定义`_switchFormToSignUp()`如下:
......@@ -250,7 +250,7 @@ enum FormMode { SIGNIN, SIGNUP }
![](img/7d327444-3ac6-482b-928e-4f8b4a74e5cb.png)
2. 接下来,我们将在 Develop 菜单中单击 Authentication 选项:
2. 接下来,我们将在`Develop`菜单中单击`Authentication`选项:
![](img/fb2f8dc4-c931-4180-802d-94dc04c1fa29.png)
......@@ -377,7 +377,7 @@ Future<void> signOut() async {
现在让我们看看如何在应用程序内部使身份验证生效。
# 在 SignupSigninScreen 中添加身份验证
# 在`SignupSigninScreen`中添加身份验证
在本节中,我们将在`SignupSigninScreen`中添加 Firebase 身份验证。
......@@ -446,7 +446,7 @@ AuthStatus authStatus = AuthStatus.NOT_SIGNED_IN;
}
```
使用在构造器中传递的类的实例调用`Auth`类的`getCurrentUser()`。 如果该方法返回的值不为 null,则意味着用户已经登录。因此,`_userId`字符串变量的值设置为返回的值。 另外,将`authStatus`设置为`AuthStatus.SIGNED_IN.`,否则,如果返回的值为`null`,则意味着没有用户登录,因此`authStatus`的值设置为`AuthStatus.NOT_SIGNED_IN`
使用在构造器中传递的类的实例调用`Auth`类的`getCurrentUser()`。 如果该方法返回的值不为`null`,则意味着用户已经登录。因此,`_userId`字符串变量的值设置为返回的值。 另外,将`authStatus`设置为`AuthStatus.SIGNED_IN.`,否则,如果返回的值为`null`,则意味着没有用户登录,因此`authStatus`的值设置为`AuthStatus.NOT_SIGNED_IN`
4. 现在,我们将定义另外两个方法`onSignIn()``onSignOut()`,以确保将身份验证状态正确存储在变量中,并相应地更新用户界面:
......@@ -549,7 +549,7 @@ void _onSignedIn() {
至此,应用程序的主要组件已经准备就绪,现在让我们创建最终的材质应用程序。
# 创建 main.dart
# 创建`main.dart`
`main.dart`内部,我们创建`Stateless Widget``App`,并覆盖`build()`方法,如下所示:
......@@ -824,7 +824,7 @@ if __name__ == '__main__':
python main.py
```
服务器侦听其运行系统的所有传入 IP。 通过在 0.0.0.0 IP 上运行它,可以实现这一点。 如果我们希望稍后在基于云的服务器上部署脚本,则需要这样做。 如果不指定 0.0.0.0 主机,则默认情况下会使它侦听 127.0.0.1,这不适合在公共服务器上进行部署。 [您可以在此处详细了解这些地址之间的区别](https://xprilion.com/difference-between-localhost-127.0.0.1-and-0.0.0.0/)
服务器侦听其运行系统的所有传入 IP。 通过在`0.0.0.0` IP 上运行它,可以实现这一点。 如果我们希望稍后在基于云的服务器上部署脚本,则需要这样做。 如果不指定`0.0.0.0`主机,则默认情况下会使它侦听`127.0.0.1`,这不适合在公共服务器上进行部署。 [您可以在此处详细了解这些地址之间的区别](https://xprilion.com/difference-between-localhost-127.0.0.1-and-0.0.0.0/)
在下一节中,我们将看到如何将 ReCaptcha 集成到迄今为止在该项目中构建的应用程序中。 之后,我们将把本节中构建的 API 集成到应用程序中。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册