news 2026/7/6 2:26:09

MyFramework Unity:TweenSequence 和 DOTween 有什么区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyFramework Unity:TweenSequence 和 DOTween 有什么区别

Unity 项目里做 Tween 动画,很多人第一时间会想到 DOTween。

这很正常。

DOTween 是非常成熟的 Unity Tween 引擎,常见写法很简单:

transform.DOMove(targetPos, 0.3f); transform.DOScale(Vector3.one, 0.3f); transform.DORotate(targetRot, 0.3f);

如果要做组合动画,可以使用Sequence

Sequence sequence = DOTween.Sequence(); sequence.Append(transform.DOLocalMove(targetPos, 0.3f)); sequence.Join(transform.DOScale(Vector3.one, 0.3f)); sequence.AppendInterval(0.2f); sequence.Append(transform.DOLocalMove(originPos, 0.3f));

DOTween 官方文档里也明确提供了Sequence,并且支持AppendJoinInsert等方式组织多个 Tween。Insert可以让 Tween 在指定时间点播放,Join可以让 Tween 和前一个 Tween 同时播放。

MyFramework 里也有一套自己的TweenSequence

但它的定位和 DOTween 不一样。

MyFramework 的TweenSequence不是为了重新实现一个通用 Tween 引擎。

它更像是框架内部的一套序列动画配置组件。

它服务的是:

  • 框架内 UI 动画
  • 框架内对象动画
  • Inspector 配置
  • 编辑器预览
  • 框架组件生命周期
  • Transformable统一位置、缩放、旋转控制
  • 项目里固定动画规则

所以这篇文章不是要说谁更强。

而是具体说清楚:

MyFramework 的 TweenSequence 和 DOTween 到底有什么区别。

项目地址:

https://github.com/ZHOURUIH/MyFramework


一、定位不同:通用 Tween 引擎 vs 框架内动画序列组件

DOTween 的定位是通用 Tween 引擎。

它面向的是整个 Unity 项目。

你可以用它处理:

  • Transform 动画
  • UI 动画
  • 材质动画
  • 颜色动画
  • 数值动画
  • 路径动画
  • 回调
  • 延迟
  • 循环
  • Sequence 拼接

它的优势是功能非常完整,API 也非常丰富。

典型 DOTween 写法是代码驱动:

transform.DOLocalMove(new Vector3(100.0f, 0.0f, 0.0f), 0.3f) .SetEase(Ease.OutQuad) .OnComplete(onMoveDone);

如果要组合动画,就写:

Sequence sequence = DOTween.Sequence(); sequence.Append(transform.DOLocalMove(targetPos, 0.3f)); sequence.Join(transform.DOScale(Vector3.one, 0.3f)); sequence.SetLoops(-1);

MyFramework 的TweenSequence不是这种定位。

它不是让业务层到处写链式 Tween 代码。

它更偏向:

把一个动画序列挂在对象上,然后由框架组件播放。

真实代码里,TweenSequence是一个MonoBehaviour

public class TweenSequence : MonoBehaviour { public List<TweenGroup> mGroupList = new(); public bool mLoop; private Vector3 mOriginPos; private Vector3 mOriginScale; private Vector3 mOriginRot; private bool mNeedResetOrigin; // 是否需要重置原始位置、缩放和旋转,当播放过以后就需要重置 public bool mResetWhenStop; // 停止播放时是否重置到原始位置、缩放和旋转 }

它本身挂在 Unity 对象上。

动画内容通过mGroupList配置。

播放时不是直接调用 DOTween API,而是由框架组件COMTransformableSequence驱动。

所以两者最核心的区别是:

DOTween 是通用 Tween 引擎。

TweenSequence 是 MyFramework 框架里的可配置动画序列组件。


二、组织方式不同:DOTween 用 Append / Join,TweenSequence 用 Group / Track

DOTween 组织 Sequence 的方式是代码链式调用。

比如顺序播放:

Sequence sequence = DOTween.Sequence(); sequence.Append(transform.DOLocalMove(pos0, 0.3f)); sequence.Append(transform.DOScale(scale0, 0.2f));

同时播放:

Sequence sequence = DOTween.Sequence(); sequence.Append(transform.DOLocalMove(pos0, 0.3f)); sequence.Join(transform.DOScale(scale0, 0.3f));

插入到指定时间:

sequence.Insert(0.5f, transform.DORotate(rot, 0.3f));

这种方式非常灵活。

代码里可以动态决定添加哪些 Tween,执行顺序也很自由。

MyFramework 的TweenSequence是另一种组织方式。

它不是用AppendJoin这种链式代码组织,而是用:

  • TweenSequence
  • TweenGroup
  • TweenTrack

TweenSequence里有多个TweenGroup

public List<TweenGroup> mGroupList = new();

每个TweenGroup里有多个TweenTrack

[Serializable] public class TweenGroup { public List<TweenTrack> mTrackList = new(); public float getGroupLength() { float length = 0.0f; foreach (TweenTrack track in mTrackList) { if (!track.mEnable) { continue; } length += track.mDuration; length += track.mStartDelay; } return length; } }

这里的结构很直观:

一个 Sequence 里有多个 Group。

一个 Group 里有多个 Track。

每个 Track 有自己的:

  • 类型
  • 曲线
  • 持续时间
  • 开始延迟
  • 起始值
  • 目标值
  • 是否启用
  • 目标模式
  • 起始模式

真实代码里,TweenTrack的字段是这样的:

[Serializable] public class TweenTrack { protected MyCurve mCurve; // 用于在运行时缓存曲线对象 protected Vector3 mRuntimeStart; // 缓存的起始值,避免在START_MODE.CURRENT模式下每次都要获取目标对象的当前值导致错误 protected Vector3 mRuntimeTarget; // 轨道开始播放时的目标值 protected bool mPlaying; // 是否正在播放 protected float mBeginTime; // 轨道的开始时间,由TweenSequence在buildTimeline()时设置 protected float mEndTime; // 轨道的结束时间,由TweenSequence在buildTimeline()时设置 public TARGET_MODE mTargetMode = TARGET_MODE.VALUE; // 目标值的获取方式 public START_MODE mStartMode = START_MODE.VALUE; // 起始值的获取方式 public Transform mTargetTransform; // 参考的目标节点,TRANSFORM模式 public Vector3 mTargetOffset; // 是否加偏移 public TWEEN_TYPE mType; // 轨道类型,如位置、缩放、旋转等 public int mCurveID; // 曲线ID,用于在运行时获取曲线对象 public float mDuration = 0.3f; // 持续时间 public float mStartDelay; // 开始前的延迟时间 public Vector3 mStartValue; // 起始值,在编辑器中设置,运行时根据目标对象的当前值进行调整 public Vector3 mTargetValue; // 目标值,用于VALUE模式 public bool mEnable = true; // 轨道是否启用 }

DOTween 的组织方式偏代码动态构建。

TweenSequence 的组织方式偏数据配置。

这是两者很大的区别。


三、能力边界不同:DOTween 很全,TweenSequence 只做框架需要的变换

DOTween 的能力非常丰富。

它不只支持 Transform,还支持很多 Unity 对象和属性。

常见的有:

  • Move
  • Rotate
  • Scale
  • Color
  • Fade
  • Text
  • Material
  • Path
  • Value Tween
  • Callback
  • Sequence
  • Loop
  • Ease

它适合做各种类型的 Tween 动画。

MyFramework 的TweenSequence当前能力更收敛。

它主要处理三类变换:

// 缓动的类型 public enum TWEEN_TYPE : byte { MOVE, // 平移 ROTATE, // 旋转 SCALE, // 缩放 }

也就是说,它主要围绕 Transform 的三个核心属性:

  • 位置
  • 缩放
  • 旋转

这不是因为做不了别的,而是设计目标不同。

MyFramework 的TweenSequence主要服务框架里的 UI 和对象动画。

这些动画里最常用的就是:

  • UI 移动
  • UI 缩放
  • UI 旋转
  • 节点弹出
  • 节点收起
  • 对象位移动画
  • 对象缩放动画
  • 简单循环动画

所以它没有追求 DOTween 那种完整通用能力。

它更像是:

为了框架内高频动画场景做的一套轻量配置方案。

这也是两者的取舍差异。

DOTween 适合“我想 Tween 任意属性”。

TweenSequence 适合“我想在框架规则内配置一段位置、缩放、旋转序列”。


四、播放入口不同:DOTween 返回 Tween 句柄,TweenSequence 接入 COMTransformableSequence

DOTween 播放时,一般会返回 Tween 或 Sequence 对象。

比如:

Tween tween = transform.DOLocalMove(targetPos, 0.3f); tween.Kill();

或者:

Sequence sequence = DOTween.Sequence(); sequence.Append(transform.DOLocalMove(targetPos, 0.3f)); sequence.Kill();

所以 DOTween 的生命周期通常由 Tween / Sequence 句柄控制。

MyFramework 的播放入口不是这样。

它通过框架命令CmdTransformableSequence播放。

真实代码:

// 缓动序列 public class CmdTransformableSequence { public static void execute(ITransformable obj, SequenceCallback doneCallback) { if (obj == null) { return; } if (isEditor() && obj is myUGUIObject uiObj && !uiObj.getLayout().canUIObjectUpdate(uiObj)) { logError("想要使窗口播放缓动动画,但是窗口当前未开启更新:" + uiObj.getName()); } obj.getOrAddComponent(out COMTransformableSequence com); com.setDoneCallback(doneCallback); com.setActive(true); com.play(obj.tryGetUnityComponent<TweenSequence>()); // 需要启用组件更新时,则开启组件拥有者的更新,后续也不会再关闭 obj.setNeedUpdate(true); } public static void execute(ITransformable obj) { if (obj == null) { return; } obj.getComponent(out COMTransformableSequence com); if (com == null || !com.isActive()) { return; } com.stop(true); } }

这段代码说明了 MyFramework 的特点。

业务层不是直接操作 Tween 对象。

而是:

  • 传入一个ITransformable
  • 获取或添加COMTransformableSequence
  • 从 Unity 对象上获取TweenSequence
  • 让组件开始播放
  • 自动开启对象更新

真正播放的是COMTransformableSequence

// 用于播放物体的缓动序列 public class COMTransformableSequence : GameComponent { protected SequenceCallback mDoneCallback; // 序列播放完成的回调,参数1:当前组件,参数2:是否被打断 protected TweenSequence mSequence; // 当前正在播放的缓动序列 protected float mCurrentTime; // 从上一次从头开始播放到现在的时长 protected float mTotalLength; // 序列的总长度,即所有TweenGroup中最长的长度 protected PLAY_STATE mPlayState; // 播放状态 }

更新时由框架组件推进时间:

public override void update(float elapsedTime) { base.update(elapsedTime); if (mPlayState == PLAY_STATE.PLAY) { mCurrentTime += elapsedTime; mSequence.evaluateSequence(mCurrentTime, out Vector3 pos, out Vector3 scale, out Vector3 rotation); var transformable = mComponentOwner as Transformable; transformable.setPosition(pos); transformable.setScale(scale); transformable.setRotation(rotation); // 是否结束播放 if (mCurrentTime >= mTotalLength) { if (mSequence.mLoop) { mCurrentTime -= mTotalLength; } else { stop(false); } } } }

这就是 MyFramework 的设计重点:

TweenSequence 不自己变成一个到处传递的 Tween 句柄。

它被框架组件接管,并通过 Transformable 生命周期播放。

这样做的好处是它可以和 MyFramework 的对象组件系统统一。

UI 对象、场景对象、框架 Transformable 对象,都可以走同一套组件更新流程。


五、起点和终点模式不同:TweenSequence 更强调配置时和运行时的组合

DOTween 里常见写法是直接传目标值:

transform.DOLocalMove(targetPos, 0.3f);

如果要相对移动,可以使用 DOTween 的相对模式,例如SetRelative()

MyFramework 的TweenTrack里,起点和终点有自己的模式。

起始值模式:

// 缓动的起始值的类型 public enum START_MODE : byte { VALUE, // 编辑器配置的固定值 SELF, // 播放时取节点当前值 }

目标值模式:

// 缓动的目标类型 public enum TARGET_MODE : byte { VALUE, // 固定值 TRANSFORM_REALTIME, // 指定节点,并且在移动过程中实时获取节点的值进行调整,适用于目标对象会移动的情况 TRANSFORM_SNAPSHOT, // 指定节点,但是只在开始移动时获取节点的值进行调整,适用于目标对象不会移动的情况 SELF, // 指定节点,但是只在开始移动时获取节点的值进行调整,适用于目标对象不会移动的情况 }

这里很有框架味道。

它把常见动画需求分成了几类:

第一,固定值。

比如从配置的 A 点移动到配置的 B 点。

第二,播放时取自己当前值。

比如 UI 当前在哪里,就从哪里开始弹出。

第三,目标节点快照。

比如播放开始时取某个目标节点的位置,之后不再变化。

第四,目标节点实时值。

比如目标对象会移动,动画过程中持续追踪目标位置。

TweenTrack.getTargetValue就是按这个规则取目标值:

public Vector3 getTargetValue(Transform transform) { switch (mTargetMode) { case TARGET_MODE.VALUE: return multiVector3(getParentAnchorScale(transform), mTargetValue); case TARGET_MODE.TRANSFORM_REALTIME: return generateTargetValue(mTargetTransform); case TARGET_MODE.TRANSFORM_SNAPSHOT: return mRuntimeTarget; case TARGET_MODE.SELF: return mRuntimeTarget; } Debug.LogError("Unsupported tween type:" + mType); return Vector3.zero; }

播放开始时会缓存运行时起点和目标点:

// 开始播放 public void play(Transform transform) { mPlaying = true; // 起点只能在开始播放时获取,终点可以实时获取 switch (mStartMode) { case START_MODE.VALUE: mRuntimeStart = multiVector3(getParentAnchorScale(transform), mStartValue); break; case START_MODE.SELF: mRuntimeStart = getTransformValue(transform); break; } if (mTargetMode == TARGET_MODE.TRANSFORM_SNAPSHOT) { mRuntimeTarget = generateTargetValue(mTargetTransform); } else if (mTargetMode == TARGET_MODE.SELF) { mRuntimeTarget = generateTargetValue(transform); } }

这说明 TweenSequence 的重点不是链式 API 灵活拼装。

它更强调:

动画可以配置好,但播放时仍然能根据当前对象状态和目标节点状态计算起点和终点。

这对 UI 很有用。

比如一个界面元素可能因为分辨率、适配、父节点缩放不同,最终位置不一定固定。

如果起点、终点完全写死,适配会比较麻烦。

TweenSequence 里还会处理ScaleAnchor

protected static Vector3 getParentAnchorScale(Transform transform) { Transform parent = transform.parent; if (parent != null && parent.TryGetComponent(out ScaleAnchor anchor)) { return getScreenScale(anchor.mAspectBase); } return Vector3.zero; }

这说明它和框架 UI 适配体系也有关系。

DOTween 更通用。

TweenSequence 更项目化。


六、预览方式不同:TweenSequence 有自己的 Inspector 编辑和预览

DOTween 主要是代码驱动。

当然也可以配合第三方工具或自己写编辑器,但 DOTween 本身最常见的使用方式还是代码调用。

MyFramework 的 TweenSequence 本身带 Inspector 编辑器。

TweenSequenceAuthoringEditor是它的自定义 Inspector:

[CustomEditor(typeof(TweenSequence))] [CanEditMultipleObjects] public class TweenSequenceAuthoringEditor : GameInspector { private TweenSequence mSequence; private bool mPlaying; private float mPreviewTime; private double mStartTime; }

编辑器里可以添加 Group:

if (button("Add Group")) { Undo.RecordObject(mSequence, "Add Group"); mSequence.mGroupList.Add(new TweenGroup()); EditorUtility.SetDirty(mSequence); }

可以添加 Track:

if (button("Add Track")) { Undo.RecordObject(mSequence, "Add Track"); group.mTrackList.Add(new TweenTrack()); }

可以选择类型、曲线、持续时间、延迟、起始值、目标值。

比如这里显示 Track 的核心配置:

toggle("Enable", ref track.mEnable); displayEnum("Type", ref track.mType); int[] ids = EditorCurveFactory.getIDs(); if (ids.Length == 0) { return; } if (track.mCurveID == 0) { track.setCurveID(ids[0]); } ids.find(track.mCurveID, out int curIndex); int newIndex = EditorGUILayout.Popup("Curve", curIndex, EditorCurveFactory.getNames()); track.setCurveID(ids[newIndex]); EditorGUILayout.CurveField("Preview", EditorCurveFactory.getPreviewCurve(track.mCurveID), GUILayout.Height(20)); displayFloat("Duration", ref track.mDuration); displayFloat("StartDelay", ref track.mStartDelay);

它还支持在编辑器里预览。

点击播放时:

private void StartPlay() { mPlaying = true; // 播放之前先确认所有轨道都是在停止状态的 mSequence.stop(true); mSequence.play(); mStartTime = EditorApplication.timeSinceStartup; EditorApplication.update -= UpdatePreview; EditorApplication.update += UpdatePreview; }

预览更新时会直接调用:

mSequence.evaluateSequence(currentTime, out Vector3 pos, out Vector3 scale, out Vector3 rot); Transform transform = mSequence.transform; transform.localPosition = pos; transform.localScale = scale; transform.localEulerAngles = rot;

这点和 DOTween 的使用习惯不同。

TweenSequence 的动画可以提前挂在对象上,在 Inspector 里调整和预览。

DOTween 更适合代码里临时组合、动态创建 Tween。

所以这里的区别是:

DOTween 更像程序式动画工具。

TweenSequence 更像框架内可配置动画组件。


七、停止和还原逻辑不同:TweenSequence 内置原始 Transform 记录

DOTween 停止动画时,通常会通过 Tween 或 Sequence 句柄调用:

tween.Kill(); sequence.Kill();

是否回到初始状态,需要自己处理,或者使用其他方式组合。

MyFramework 的TweenSequence内部会记录播放前的位置、缩放、旋转。

播放时记录:

public void play() { if (mLoop && hasSelfValueType()) { logError("存在SELF模式轨道时不允许循环播放"); mLoop = false; } // 开始播放时设置每个Track的开始时间和结束时间 foreach (TweenGroup group in mGroupList) { float time = 0.0f; foreach (TweenTrack track in group.mTrackList) { if (!track.mEnable) { continue; } time += track.mStartDelay; track.setBeginTime(time); time += track.mDuration; track.setEndTime(time); } } mOriginPos = transform.localPosition; mOriginScale = transform.localScale; mOriginRot = transform.localEulerAngles; mNeedResetOrigin = true; }

停止时可以还原:

public void stop(bool forceReset = false) { foreach (var group in mGroupList) { foreach (var track in group.mTrackList) { track.stop(); } } if (mNeedResetOrigin && (mResetWhenStop || forceReset)) { transform.localPosition = mOriginPos; transform.localScale = mOriginScale; transform.localEulerAngles = mOriginRot; mNeedResetOrigin = false; } }

这里的mResetWhenStop是 Inspector 上的配置。

这说明 TweenSequence 把“停止时是否恢复原始状态”作为组件行为的一部分。

这个设计很适合 UI。

比如一个窗口打开时播放弹出动画,关闭或停止时希望回到原始 Transform。

如果每次都让调用方自己记原始坐标,就会很重复。

TweenSequence 直接把这件事放进组件里处理。


八、循环限制不同:TweenSequence 禁止 SELF 模式循环

DOTween 的循环能力很强。

常见写法是:

tween.SetLoops(-1);

或者:

sequence.SetLoops(-1);

MyFramework 的 TweenSequence 也支持循环:

public bool mLoop;

但是它有一个限制:

存在 SELF 模式轨道时不允许循环播放。

真实代码:

public void play() { if (mLoop && hasSelfValueType()) { logError("存在SELF模式轨道时不允许循环播放"); mLoop = false; } ... }

TweenGroup里会检查是否存在 SELF:

public bool hasSelfValueType() { foreach (TweenTrack track in mTrackList) { if (track.mStartMode == START_MODE.SELF || track.mTargetMode == TARGET_MODE.SELF) { return true; } } return false; }

Editor 里也会禁止勾选 Loop:

EditorGUI.BeginDisabledGroup(mSequence.hasSelfValueType()); toggle("Loop", ref mSequence.mLoop); EditorGUI.EndDisabledGroup(); if (mSequence.hasSelfValueType()) { mSequence.mLoop = false; EditorGUILayout.HelpBox("存在SELF模式轨道时不允许循环播放", MessageType.Warning); }

这个限制很合理。

因为 SELF 模式会在播放时取当前对象状态。

如果循环播放,每一轮的起点或目标可能不断基于上一次结果变化,容易出现位置、缩放、旋转持续偏移。

所以 TweenSequence 直接在规则层限制掉。

这也是框架内工具和通用工具的区别。

DOTween 给你更大的自由度。

TweenSequence 会加更多项目规则,避免常见错误。


九、适合场景不同

DOTween 更适合这些场景:

  • 代码里动态创建动画
  • 需要 Tween 任意属性
  • 需要丰富 Ease 类型
  • 需要 Path、Punch、Shake 等复杂 Tween
  • 需要完整 Tween 生态
  • 需要快速写临时动画
  • 需要和第三方工具或插件配合
  • 项目没有自己的动画组件体系

MyFramework 的 TweenSequence 更适合这些场景:

  • 动画挂在 Prefab 上配置
  • 希望在 Inspector 里编辑和预览
  • 动画主要是位置、缩放、旋转
  • UI 打开、关闭、提示、弹出这类固定动画
  • 需要接入Transformable组件体系
  • 需要统一setPosition / setScale / setRotation
  • 需要停止时恢复初始状态
  • 需要限制 SELF 模式循环这类项目规则
  • 不希望业务层直接管理 Tween 句柄

所以这两个东西不是同一个目标。

DOTween 更适合通用 Tween 编程。

TweenSequence 更适合 MyFramework 内部的可配置动画序列。


总结

MyFramework 的TweenSequence和 DOTween 最大的区别,不是能不能移动、缩放、旋转。

而是定位不同。

DOTween 是成熟的通用 Tween 引擎。

它提供丰富 API,适合代码动态创建各种动画。

MyFramework 的TweenSequence是框架内部的动画序列组件。

它通过:

  • TweenSequence
  • TweenGroup
  • TweenTrack
  • COMTransformableSequence
  • CmdTransformableSequence

把一段位置、缩放、旋转动画接入自己的框架生命周期。

从代码上可以看到:

  • TweenSequence负责保存 Group 和 Track
  • TweenGroup负责组织一组轨道
  • TweenTrack负责单条轨道的类型、曲线、起点、终点、延迟和持续时间
  • COMTransformableSequence负责更新时间并把结果设置到Transformable
  • CmdTransformableSequence负责对外提供统一播放和停止入口
  • TweenSequenceAuthoringEditor负责 Inspector 配置和编辑器预览

所以它不是为了替代 DOTween。

它解决的是另一个问题:

如何让动画序列成为 MyFramework 自己框架体系的一部分。

一句话总结:

DOTween 更像一个强大的通用动画引擎。

TweenSequence 更像 MyFramework 内部的可配置动画组件。

通用引擎适合解决各种 Tween 需求。

框架内组件适合解决项目里固定、可配置、可预览、可接入生命周期的动画流程。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/6 2:25:01

HTML5+CSS3 登录注册页面实战:从零构建 2 个响应式表单(附完整源码)

HTML5CSS3 登录注册页面实战&#xff1a;从零构建 2 个响应式表单&#xff08;附完整源码&#xff09;在当今数字化时代&#xff0c;登录和注册页面是用户与网站或应用交互的第一道门槛。一个设计精良的表单不仅能提升用户体验&#xff0c;还能增加用户留存率。本文将带你从零开…

作者头像 李华
网站建设 2026/7/6 2:24:12

深度学习计算图与反向传播原理详解:从手动实现到梯度流动

&#x1f680; 30款热门AI模型一站整合&#xff0c;DeepSeek/GLM/Qwen 随心用&#xff0c;限时 5 折。 &#x1f449; 点击领海量免费额度 这次我们来看一个深度学习框架中的核心概念&#xff1a;计算图与反向传播。对于任何想要深入理解神经网络训练过程&#xff0c;特别是…

作者头像 李华
网站建设 2026/7/6 2:23:56

flask之定义URL

flask定义URL分为无参的URL与有参的URLURL可以理解为网址无参的URL指在定义的过程中&#xff0c;不需要定义参数app.route(/profile) def profile():return "这是个人中心"有参的URL指的是带参数的URL语法&#xff1a;app.route(网址路径/<参数名>)def 方法名(…

作者头像 李华
网站建设 2026/7/6 2:21:21

Momentum 优化算法 PyTorch 实战:对比 SGD 在 ResNet-18 上收敛速度提升 30%

Momentum优化算法在PyTorch中的实战&#xff1a;ResNet-18训练效率提升30%的完整指南深度学习的训练过程往往需要耗费大量计算资源&#xff0c;而优化算法的选择直接影响模型收敛速度和最终性能。本文将带你深入探索Momentum优化算法在PyTorch框架下的实战应用&#xff0c;通过…

作者头像 李华
网站建设 2026/7/6 2:18:16

E-R 模型向关系模式转换:8种场景实战与 MySQL 8.0 建表示例

E-R 模型向关系模式转换&#xff1a;8种场景实战与 MySQL 8.0 建表示例 在数据库设计的逻辑结构设计阶段&#xff0c;将概念模型&#xff08;E-R图&#xff09;转换为关系模式是一个关键步骤。这个过程直接决定了数据库的结构是否合理、高效。本文将深入探讨8种典型E-R联系类型…

作者头像 李华