TiDB 最佳实践系列(三)乐观锁事务

TiDB事务隔离级别和并发控制的特点详述        TiDB作为新一代分布式SQL数据库,它支持强一致性事务。ANSI SQL-92 对于事务的隔离级别有明确的定义,这也是大部分传统数据库(MySQL、PostgreSQL、Oracle、DB2、SqlServer等)都遵循的标准。TiDB的事务隔离级别并没有完全支持ANSI标准中的所有隔离级别,它缺省的隔离级别是"Snapshot Isolation"(简称SI),这种隔离级别类似于... 阅读详情

TiDB 最佳实践系列是面向广大 TiDB 用户的系列教程,旨在深入浅出介绍 TiDB 的架构与原理,帮助用户在生产环境中最大限度发挥 TiDB 的优势。我们将分享一系列典型场景下的最佳实践路径,便于大家快速上手,迅速定位并解决问题。

在前两篇的文章中,我们分别介绍了 TiDB 高并发写入常见热点问题及规避方法 和 PD 调度策略最佳实践,本文我们将深入浅出介绍 TiDB 乐观事务原理,并给出多种场景下的最佳实践,希望大家能够从中收益。同时,也欢迎大家给我们提供相关的优化建议,参与到我们的优化工作中来。

建议大家在阅读之前先了解 TiDB 的整体架构 和 Percollator 事务模型。另外,本文重点关注原理及最佳实践路径,具体的 TiDB 事务语句大家可以在 官方文档 中查阅。

TiDB 事务定义

TiDB 使用 Percolator 事务模型,实现了分布式事务(建议未读过该论文的同学先浏览一下 论文 中事务部分内容)。

说到事务,不得不先抛出事务的基本概念。通常我们用 ACID 来定义事务(ACID 概念定义)。下面我们简单说一下 TiDB 是怎么实现 ACID 的:

  • A(原子性):基于单实例的原子性来实现分布式事务的原子性,和 Percolator 论文一样,TiDB 通过使用 Primary Key 所在 region 的原子性来保证。
  • C(一致性):本身 TiDB 在写入数据之前,会对数据的一致性进行校验,校验通过才会写入内存并返回成功。
  • I(隔离性):隔离性主要用于处理并发场景,TiDB 目前只支持一种隔离级别 Repeatable Read,即在事务内可重复读。
  • D(持久性):事务一旦提交成功,数据全部持久化到 TiKV, 此时即使 TiDB 服务器宕机也不会出现数据丢失。

截止本文发稿时,TiDB 一共提供了两种事务模式:乐观事务和悲观事务。那么乐观事务和悲观事务有什么区别呢?最本质的区别就是什么时候检测冲突:

  • 悲观事务:顾名思义,比较悲观,对于每一条 SQL 都会检测冲突。
  • 乐观事务:只有在事务最终提交 commit 时才会检测冲突。

下面我们将着重介绍乐观事务在 TiDB 中的实现。另外,想要了解 TiDB 悲观事务更多细节的同学,可以先阅读本文,思考一下在 TiDB 中如何实现悲观事务,我们后续也会提供《悲观锁事务最佳实践》给大家参考。

乐观事务原理

有了 Percolator 基础后,下面我们来介绍 TiDB 乐观锁事务处理流程。

TiDB 在处理一个事务时,处理流程如下:

  1. 客户端 begin 了一个事务。
    a. TiDB 从 PD 获取一个全局唯一递增的版本号作为当前事务的开始版本号,这里我们定义为该事务的 start_ts。
  2. 客户端发起读请求。
    a. TiDB 从 PD 获取数据路由信息,数据具体存在哪个 TiKV 上。
    b. TiDB 向 TiKV 获取 start_ts 版本下对应的数据信息。
  3. 客户端发起写请求。
    a. TiDB 对写入数据进行校验,如数据类型是否正确、是否符合唯一索引约束等,确保新写入数据事务符合一致性约束,将检查通过的数据存放在内存里。
  4. 客户端发起 commit。
  5. TiDB 开始两阶段提交将事务原子地提交,数据真正落盘。
    a. TiDB 从当前要写入的数据中选择一个 Key 作为当前事务的 Primary Key。
    b. TiDB 从 PD 获取所有数据的写入路由信息,并将所有的 Key 按照所有的路由进行分类。
    c. TiDB 并发向所有涉及的 TiKV 发起 prewrite 请求,TiKV 收到 prewrite 数据后,检查数据版本信息是否存在冲突、过期,符合条件给数据加锁。
    d. TiDB 收到所有的 prewrite 成功。
    e. TiDB 向 PD 获取第二个全局唯一递增版本,作为本次事务的 commit_ts。
    f. TiDB 向 Primary Key 所在 TiKV 发起第二阶段提交 commit 操作,TiKV 收到 commit 操作后,检查数据合法性,清理 prewrite 阶段留下的锁。
    g. TiDB 收到 f 成功信息。
  6. TiDB 向客户端返回事务提交成功。
  7. TiDB 异步清理本次事务遗留的锁信息。

优缺点分析

从上面这个过程可以看到, TiDB 事务存在以下优点:

  • 简单,好理解。
  • 基于单实例事务实现了跨节点事务。
  • 去中心化的锁管理。

缺点如下:

  • 两阶段提交,网络交互多。
  • 需要一个中心化的版本管理服务。
  • 事务在 commit 之前,数据写在内存里,数据过大内存就会暴涨。

基于以上缺点的分析,我们有了一些实践建议,将在下文详细介绍。

事务大小

1. 小事务

为了降低网络交互对于小事务的影响,我们建议小事务打包来做。如在 auto commit 模式下,下面每条语句成为了一个事务:

# original version with auto_commit
UPDATE my_table SET a='new_value' WHERE id = 1; 
UPDATE my_table SET a='newer_value' WHERE id = 2;
UPDATE my_table SET a='newest_value' WHERE id = 3;

以上每一条语句,都需要经过两阶段提交,网络交互就直接 *3, 如果我们能够打包成一个事务提交,性能上会有一个显著的提升,如下:

# improved version
START TRANSACTION;
UPDATE my_table SET a='new_value' WHERE id = 1; 
UPDATE my_table SET a='newer_value' WHERE id = 2;
UPDATE my_table SET a='newest_value' WHERE id = 3;
COMMIT;

同理,对于 insert 语句也建议打包成事务来处理。

2. 大事务

既然小事务有问题,我们的事务是不是越大越好呢?

我们回过头来分析两阶段提交的过程,聪明如你,很容易就可以发现,当事务过大时,会有以下问题:

  • 客户端 commit 之前写入数据都在内存里面,TiDB 内存暴涨,一不小心就会 OOM。
  • 第一阶段写入与其他事务出现冲突的概率就会指数级上升,事务之间相互阻塞影响。
  • 事务的提交完成会变得很长很长 ~~~

为了解决这个问题,我们对事务的大小做了一些限制:

  • 单个事务包含的 SQL 语句不超过 5000 条(默认)
  • 每个键值对不超过 6MB
  • 键值对的总数不超过 300,000
  • 键值对的总大小不超过 100MB

因此,对于 TiDB 乐观事务而言,事务太大或者太小,都会出现性能上的问题。我们建议每 100~500 行写入一个事务,可以达到一个比较优的性能。

事务冲突

事务的冲突,主要指事务并发执行时,对相同的 Key 有读写操作,主要分两种:

  • 读写冲突:存在并发的事务,部分事务对相同的 Key 读,部分事务对相同的 Key 进行写。
  • 写写冲突:存在并发的事务,同时对相同的 Key 进行写入。

在 TiDB 的乐观锁机制中,因为是在客户端对事务 commit 时,才会触发两阶段提交,检测是否存在写写冲突。所以,在乐观锁中,存在写写冲突时,很容易在事务提交时暴露,因而更容易被用户感知。

默认冲突行为

因为我们本文着重将乐观锁的最佳实践,那么我们这边来分析一下乐观事务下,TiDB 的行为。

默认配置下,以下并发事务存在冲突时,结果如下:

在这个 case 中,现象分析如下:

  • 如上图,事务 A 在时间点 t1 开始事务,事务 B 在事务 t1 之后的 t2 开始。
  • 事务 A、事务 B 会同时去更新同一行数据。
  • 时间点 t4 时,事务 A 想要更新 id = 1 的这一行数据,虽然此时这行数据在 t3 这个时间点被事务 B 已经更新了,但是因为 TiDB 乐观事务只有在事务 commit 时才检测冲突,所以时间点 t4 的执行成功了。
  • 时间点 t5,事务 B 成功提交,数据落盘。
  • 时间点 t6,事务 A 尝试提交,检测冲突时发现 t1 之后有新的数据写入,返回冲突,事务 A 提交失败,提示客户端进行重试。

根据乐观锁的定义,这样做完全符合逻辑。

重试机制

我们知道了乐观锁下事务的默认行为,可以知道在冲突比较大的时候,Commit 很容易出现失败。然而,TiDB 的大部分用户,都是来自于 MySQL;而 MySQL 内部使用的是悲观锁。对应到这个 case,就是事务 A 在 t4 更新时就会报失败,客户端就会根据需求去重试。

换言之,MySQL 的冲突检测在 SQL 执行过程中执行,所以 commit 时很难出现异常。而 TiDB 使用乐观锁机制造成的两边行为不一致,则需要客户端修改大量的代码。 为了解决广大 MySQL 用户的这个问题,TiDB 提供了内部默认重试机制,这里,也就是当事务 A commit 发现冲突时,TiDB 内部重新回放带写入的 SQL。为此 TiDB 提供了以下参数,

如何设置以上参数呢?推荐两种方式设置:

  1. session 级别设置:
    set @@tidb_disable_txn_auto_retry = 0; set @@tidb_retry_limit = 10;
  2. 全局设置:
    set @@global.tidb_disable_txn_auto_retry = 0; set @@global.tidb_retry_limit = 10;

万能重试

那么重试是不是万能的呢?这要从重试的原理出发,重试的步骤:

  1. 重新获取 start_ts。
  2. 对带写入的 SQL 进行重放。
  3. 两阶段提交。

细心如你可能会发现,我们这边只对写入的 SQL 进行回放,并没有提及读取 SQL。这个行为看似很合理,但是这个会引发其他问题:

  1. start_ts 发生了变更,当前这个事务中,读到的数据与事务真正开始的那个时间发生了变化,写入的版本也是同理变成了重试时获取的 start_ts 而不是事务一开始时的那个。
  2. 如果当前事务中存在更新依赖于读到的数据,结果变得不可控。

打开了重试后,我们来看下面的例子:

我们来详细分析以下这个 case:

  • 如图,在 session B 在 t2 开始事务 2,t5 提交成功。session A 的事务 1 在事务 2 之前开始,在事务 n2 提交完成后提交。
  • 事务 1、事务 2 会同时去更新同一行数据。
  • session A 提交事务 1 时,发现冲突,tidb 内部重试事务 1。
    • 重试时,重新取得新的 start_ts 为 t8’。
    • 回放更新语句 update tidb set name='pd' where id =1 and status=1。
      i. 发现当前版本 t8’ 下并不存在符合条件的语句,不需要更新。
      ii. 没有数据更新,返回上层成功。
  • tidb 认为事务 1 重试成功,返回客户端成功。
  • session A 认为事务执行成功,查询结果,在不存在其他更新的情况下,发现数据与预想的不一致。

这里我们可以看到,对于重试事务,如果本身事务中更新语句需要依赖查询结果时,因为重试时会重新取版本号作为 start_ts,因而无法保证事务原本的 ReadRepeatable 隔离型,结果与预测可能出现不一致。

综上所述,如果存在依赖查询结果来更新 SQL 语句的事务,建议不要打开 TiDB 乐观锁的重试机制。

冲突预检

从上文我们可以知道,检测底层数据是否存在写写冲突是一个很重的操作,因为要读取到数据进行检测,这个操作在 prewrite 时 TiKV 中具体执行。为了优化这一块性能,TiDB 集群会在内存里面进行一次冲突预检测。

TiDB 作为一个分布式系统,我们在内存中的冲突检测主要在两个模块进行:

  • TiDB 层,如果在 TiDB 实例本身发现存在写写冲突,那么第一个写入发出去后,后面的写入就已经能清楚地知道自己冲突了,没必要再往下层 TiKV 发送请求去检测冲突。
  • TiKV 层,主要发生在 prewrite 阶段。因为 TiDB 集群是一个分布式系统,TiDB 实例本身无状态,实例之间无法感知到彼此的存在,也就无法确认自己的写入与别的 TiDB 实例是否存在冲突,所以会在 TiKV 这一层检测具体的数据是否有冲突。

其中 TiDB 层的冲突检测可以关闭,配置项可以启用:

txn-local-latches:事务内存锁相关配置,当本地事务冲突比较多时建议开启。

  • enable
    • 开启
    • 默认值:false
  • capacity
    • Hash 对应的 slot 数,会自动向上调整为 2 的指数倍。每个 slot 占 32 Bytes 内存。当写入数据的范围比较广时(如导数据),设置过小会导致变慢,性能下降。
    • 默认值:1024000

细心的朋友可能又注意到,这边有个 capacity 的配置,它的设置主要会影响到冲突判断的正确性。在实现冲突检测时,我们不可能把所有的 Key 都存到内存里,占空间太大,得不偿失。所以,真正存下来的是每个 Key 的 hash 值,有 hash 算法就有碰撞也就是误判的概率,这里我们通过 capacity 来控制 hash 取模的值:

  • capacity 值越小,占用内存小,误判概率越大。
  • capacity 值越大,占用内存大,误判概率越小。

在真实使用时,如果业务场景能够预判断写入不存在冲突,如导入数据操作,建议关闭。

相应地,TiKV 内存中的冲突检测也有一套类似的东西。不同的是,TiKV 的检测会更严格,不允许关闭,只提供了一个 hash 取模值的配置项:

  • scheduler-concurrency
    • scheduler 内置一个内存锁机制,防止同时对一个 Key 进行操作。每个 Key hash 到不同的槽。
    • 默认值:2048000

此外,TiKV 提供了监控查看具体消耗在 latch 等待的时间:

如果发现这个 wait duration 特别高,说明耗在等待锁的请求上比较久,如果不存在底层写入慢问题的话,基本上可以判断这段时间内冲突比较多。

总结

综上所述,Percolator 乐观事务实现原理简单,但是缺点诸多,为了优化这些缺陷带来的性能上和功能上的开销,我们做了诸多努力。但是谁也不敢自信满满地说:这一块的性能已经达到了极致。

时至今日,我们还在持续努力将这一块做得更好更远,希望能让更多使用 TiDB 的小伙伴能从中受益。与此同时,我们也非常期待大家在使用过程中的反馈,如果大家对 TiDB 事务有更多优化建议,欢迎联系我 wuxuelian@pingcap.com 。您看似不经意的一个举动,都有可能使更多饱受折磨的互联网同学们从中享受到分布式事务的乐趣。

原文阅读:

TiDB 最佳实践系列(三)乐观锁事务 | PingCAP​pingcap.com

 

TiDB 最佳实践 数据库是一个通用的基础组件,在开发过程中会考虑到多种目标场景,在具体的业务场景中,需要根据业务的实际情况对数据的参数或者使用方式进行调整。TiDB是一个兼容MySQL协议和语法的分布式数据库,但是由于其内部实现,特别是支持分布式存储以及分布式事务,使得一些使用方法和MySQL有所区别。... 阅读详情

相关推荐

TiDB write conflict问题排查

背景 我们线上使用TiDB来储存数据,最近DBA报告TiDB发生了write conflict. [2020/08/25 06:01:44.781 +08:00] [WARN] [session.go:623] [retrying] [conn=26799778] [schemaVersion=194] [retryCnt=0] [queryNum=0] [sql="UPDATE user_tab SET `region` = ?, `status` = ?, `update_time` = ? WHERE

【码农在新加坡】的专栏 2814

TiDB事物隔离级别以及乐观锁模型介绍

     TiDB支持ANSI SQL-92标准中的“读已提交”和“可重复读”两种事物隔离级别。对于“可重复读”隔离级别,在TiDB中叫做“Snapshot Isolation”(快照隔离级别,简称SI),这种隔离级别不会产生“幻像读”,但是会产生写偏斜(write skew)。TiDB缺省的事物隔离级别是SI,可以通过相关语句设置为“读已提交”隔离级别。     注意:         (1) ...

“IT-老兵” 的博客 2902

TiDB 事务流程与乐观锁的最佳实践

需要注意的是,在使用乐观锁时,我们需要在执行更新操作之前再次检查数据是否仍然符合预期。如果在更新操作之前发现数据已经发生变化,我们可以选择中止事务并进行回滚,或者重新尝试更新操作。在 TiDB 中,乐观锁使用乐观并发控制(Optimistic Concurrency Control,简称 OCC)算法来解决并发冲突。TiDB 是一个分布式的 NewSQL 数据库,其事务流程和乐观锁的使用是确保数据强一致性和并发控制的关键方面。函数执行更新操作,并在更新时使用 WHERE 子句中的条件实现乐观锁。

FdhApps的博客 103

TiDB和MySQL的锁一些分析比对

原文来源: https://tidb.net/blog/1c1a2ab7 ...

TiDB 社区干货传送门 518

Voronoi算法构建多晶

孪晶多晶 采用孪晶的原子链作为种子通过voronoi算法可以得到孪晶多晶结构。 孪晶种子: txt文件不需要特殊设置 box 150 150 150 random 8 得到孪晶多晶: 通过改变孪晶种子的长度可以得到不同孪晶片层厚度的多晶。 准二维柱晶 所有晶粒在某一维度的晶向一致,晶粒仅在平面内具有旋转关系,所有晶界为旋转对称晶界,这种结构的多晶其位错滑移在某些方向受限,但是能极大的提高晶粒...

yamatachi的博客 5280

零基础也能懂的Arduino ESP32离线安装包图文教程

手把手教你完成Arduino ESP32离线安装包的配置,无需联网也能快速搭建开发环境,适合初学者和网络受限用户,轻松实现arduino esp32离线安装包部署。

weixin_36213081的博客 2670

TiDB 事务冲突解决:乐观锁与重试策略

TiDB 的事务处理基于乐观并发控制(Optimistic Concurrency Control, OCC)。与悲观锁(如行级锁)不同,乐观锁假设事务冲突概率低,因此事务执行期间不加锁,只在提交阶段进行冲突检查。这提高了并发性能,尤其适合读多写少的场景。每个事务在开始时分配一个唯一开始时间戳 $T_{\text{start}}$。数据行(或 Key-Value 对)存储一个提交时间戳 $T_{\text{commit}}$。

2501_93894412的博客 370

NVIDIA显卡在Linux下的功率限制问题:RTX 3060 Laptop的解决方案与避坑指南

本文针对NVIDIA RTX 3060 Laptop显卡在Linux系统下遭遇功率限制的问题,提供了详细的诊断与解决方案。通过使用nvidia-smi工具监控显卡状态,并重点介绍了通过升级驱动、启用nvidia-powerd服务来激活Dynamic Boost 2.0功能,从而安全、智能地解锁额外显卡功率,有效提升性能。

weixin_29290947的博客 634

TIDB 乐观事务和悲观事务

1.TIDB 乐观事务和悲观事务。

weixin_43346403的博客 420

CTR-GCN 论文解读

提出了一种信道拓扑优化图卷积,该卷积可以动态有效地对信道拓扑进行建模。共享拓扑是一个参数化的邻接矩阵,作为所有通道的拓扑先验,并提供顶点之间的一般相关性。通过使用特定于通道的相关性细化共享拓扑,CTR-GC 获得了通道拓扑。

一杯水果茶!足矣~ 3088

【数据集】全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

全球大气空气柱平均甲烷(XCH₄)和一氧化碳(XCO)浓度数据集 TROPOMI/WFMD

WW、forever的博客 387

升级就是最好的调优:TiDB 用户收益与实践总结报告

作者: Lucien-卢西恩 原文来源: https://tidb.net/blog/59300cbe ...

TiDB 社区干货传送门 1235

让 PyCharm 代码“发光”:高亮插件与特效全攻略

PyCharm 作为一款强大的 Python IDE,支持多种插件让代码“发光”——无论是动态输入特效、彩虹括号,还是霓虹主题,都能让你的代码脱颖而出!进入 File → Settings → Editor → Color Scheme → Rainbow Brackets。进入 File → Settings → Appearance & Behavior → Material Theme。进入 File → Settings → Editor → Color Scheme → General。

qq_43580271的博客 3834

事务提交 commit 会失败么_TiDB 最佳实践系列(三)乐观锁事务

作者:ShirlyTiDB 最佳实践系列是面向广大 TiDB 用户的系列教程,旨在深入浅出介绍 TiDB 的架构与原理,帮助用户在生产环境中最大限度发挥 TiDB 的优势。我们将分享一系列典型场景下的最佳实践路径,便于大家快速上手,迅速定位并解决问题。在前两篇的文章中,我们分别介绍了 TiDB 高并发写入常见热点问题及规避方法 和 PD 调度策略最佳实践,本文我们将深入浅出介绍 TiDB 乐观事务...

weixin_39619170的博客 331

AI 时代嵌入式工程师的能力模型与学习路线:全系列收官

AI 时代嵌入式工程师的能力模型与学习路线:全系列收官

weixin_42162924的博客 33

Open3D(C++) 读取、可视化并保存点云【2025最新版】

博客长期更新,本文最近更新时间为:2025年1月6日。

点云侠的博客 4617

【TiDB 最佳实践系列】乐观锁事务

原文来源: https://tidb.net/blog/48d7f732 ...

TiDB 社区干货传送门 146

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

TiDB-从0到1-分布式事务

TiDB-从0到1-分布式事务介绍

MZZHAO23的博客 2054

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

香,聊聊TiDB的分布式事务模型

公众号:程序员jinjunzhu

zjj2006的专栏 2210

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

TiDB最佳实践

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34365635的博客 715

TiDB分布式事务—写写冲突

作者: Hacker_Yv76YjBL 原文来源: https://tidb.net/blog/5682e17e ...

TiDB 社区干货传送门 1620
上一篇: Nginx实战-后端应用健康检查
下一篇: finalize()
wrr-cat
博客等级 码龄9年 128粉丝 302原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值