草庐IT

Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择

中杯可乐多加冰 2023-04-12 原文

GigaGAN是Adobe和卡内基梅隆大学学者们提出的一种新的GAN架构,作者设计了一种新的GAN架构,推理速度、合成高分辨率、扩展性都极其有优势,其证明GAN仍然是文本生成图像的可行选择之一。

文章链接:https://arxiv.org/abs/2303.05511
项目地址:https://mingukkang.github.io/GigaGAN/

一、原文摘要

最近,文字-图像合成技术的成功已经席卷全球,激发了大众的想象力。从技术的角度来看,它也标志着设计生成图像模型所青睐的架构的巨大变化。GANs曾经是事实上的选择,有StyleGAN这样的技术。随着DALL·e2的出现,自回归和扩散模型一夜之间成为大规模生成模型的新标准。这种快速的转变提出了一个基本问题:我们能否扩大GANs的规模,从像LAION这样的大型数据集中受益?我们发现,随意增加StyleGAN架构的容量很快就会变得不稳定。我们介绍了一种新的GAN架构GigaGAN,它远远超过了这一限制,证明了GAN是文本到图像合成的可行选择。GigaGAN有三大优势。首先,它的推理速度快了几个数量级,合成一张512px的图像只需要0.13秒。其次,它可以在3.66秒内合成高分辨率图像,例如1600万像素的图像。最后,GigaGAN支持各种潜在空间编辑应用程序,如潜在插值、样式混合和矢量算术操作。

二、为什么提出GigaGAN?

最近发布的模型如DALL·E 2、Imagen、Parti和Stable Diffusion开创了图像生成的新时代,实现了前所未有的图像质量和模型灵活性。目前占主导地位的扩散模型和自回归模型都依赖于迭代推理,然而众所周知,迭代推理是一把双刃剑,虽然迭代方法可以实现简单目标的稳定训练,但在推理过程中会产生很高的计算成本

而生成对抗网络只需通过单次向前传递生成图像,相较而言非常高效,其在建模单个或多个对象类方面表现出色,但在扩大规模时会经常遇见模式崩溃,在扩展到复杂的数据集或者更加开放的世界,仍然具有挑战性。

于是,作者提出了一系列问题:

  • GANs能否继续扩大规模,并可能从这些复杂资源中受益,还是已经停滞不前?
  • 是什么阻止了它们进一步扩大,我们能克服这些障碍吗?

在这些问题的基础上,作者首先研究分析了StyleGAN的关键问题,其次重新引入了多尺度训练,找到了一种改进图像-文本对齐和生成输出的低频细节的新方案——GigaGAN,与扩散和自回归模型相比,GigaGAN有三个主要的实际优势:

  1. 推理速度快,在0.13秒内生成512*512像素的图像。
  2. 能合成超高清图像,可以在3.66秒内合成4k分辨率的超高分辨率图像。
  3. 可控图像合成应用,被赋予了一个可控的、潜在的向量空间,可以用于充分研究的可控图像合成应用,例如风格混合、prompt插值和prompt混合。

三、GigaGAN

3.1、模型框架

GigaGAN模型框架如上图所示,首先,作者使用预训练的CLIP模型预训练的文本编码器T提取文本嵌入。然后使用交叉注意力将本地文本描述符提供给生成器,全局文本描述符和潜在代码z一起被馈送到样式映射网络M以生成样式向量w(StyleGAN的方法)。样式向量w输入形成样本自适应核选择帮助调节主生成器。右侧显示样本自适应核选择的具体过程。

3.2、前导知识

3.2.1、基线模型:StyleGAN。

GigaGAN架构基于StyleGAN2的条件版本,由两个网络组成 G = G ~ ∘ M G=\widetilde{G} \circ M G=G M,映射网络w = M(z, c)将输入映射到一个“风格”向量w,它调制合成网络 G ~ ( w ) \widetilde{G}(\mathbf{w}) G (w)中的一系列上采样卷积层,以将学习到的常数张量映射到输出图像x。其中卷积是生成图像的主要引擎,而“风格”向量w是调节模型的信息来源。

3.2.2、 样本自适应核选择

为了处理互联网图像的高度多样化分布,文章提出了一种有效的方法来增强卷积核的表达能力,即基于文本条件处理实时创建卷积核,如下图所示

Filter Selection:这个方案中首先实例化了一组N个过滤器(图中叫Filter Bank): { K i ∈ R C in  × C out  × K × K } i = 1 N \begin{array}{c} \left\{\mathbf{K}_{i} \in {R}^{C_{\text {in }} \times C_{\text {out }} \times K \times K}\right\}_{i = 1}^{N} \end{array} {KiRCin ×Cout ×K×K}i=1N它在每一层取一个特征 f ∈ R C i n f ∈R^{C_{in}} fRCin,然后样式向量 w ∈ R d w ∈ R^d wRd经过一个仿射层来 [ W f i l t e r , b f i l t e r ] ∈ R ( d + 1 ) × N [W_{filter}, b_{filter}]∈R^{(d+1)×N} [Wfilter,bfilter]R(d+1)×N预测一组权重来平均滤波器,从而产生一个聚合滤波器 K ∈ R C i n × C o u t × K × K K ∈ R^{C_{in}×C_{out}×K×K} KRCin×Cout×K×K,计算过程如下(不了解仿射变换的可同学可以看下这篇):
K = ∑ i = 1 N K i ⋅ softmax ⁡ ( W filter  ⊤ w + b filter  ) i \mathbf{K}=\sum_{i=1}^N \mathbf{K}_i \cdot \operatorname{softmax}\left(W_{\text {filter }}^{\top} \mathbf{w}+b_{\text {filter }}\right)_i K=i=1NKisoftmax(Wfilter w+bfilter )i

然后在StyleGAN2的正则卷积管道中使用该滤波器再经过一层仿射变换 [ W f i l t e r , b f i l t e r ] ∈ R ( d + 1 ) × C i n [W_{filter}, b_{filter}]∈R^{(d+1)×C_{in}} [Wfilter,bfilter]R(d+1)×Cin进行权重调制:
g adaconv  ( f , w ) = ( ( W   m o d   ⊤ w + b mod  ) ⊗ K ) ∗ f g_{\text {adaconv }}(\mathbf{f}, \mathbf{w})=\left(\left(W_{\bmod }^{\top} \mathbf{w}+b_{\text {mod }}\right) \otimes \mathbf{K}\right) * \mathbf{f} gadaconv (f,w)=((Wmodw+bmod )K)f 其中⊗和∗表示(反)调制和卷积。

在高层次上,基于softmax的加权可以被视为基于输入条件的可微滤波器选择过程。此外,由于滤波器选择过程只在每一层执行一次,选择过程比实际的卷积快得多。
卷积滤波器在每个样本中动态变化,其与动态卷积的想法相同,但不同之处在于文章显式实例化了一个更大的滤波器组,并基于StyleGAN的w-空间条件下的单独路径选择权重。

3.2.3、将注意力与卷积交织

建立这种长期关系的一种方法就是使用注意力层。BigGAN, GANformer和ViTGAN都将注意力层与卷积主干集成在一起来提高性能,但是如果简单地给StyleGAN添加注意层往往会导致训练崩溃。这是由于鉴别器的Lipschitz连续性在稳定训练中发挥了关键作用,作者使用L2-distance代替点积作为注意对数来促进Lipschitz连续性,类似于ViTGAN

为了进一步提高性能,作者发现匹配StyleGAN的架构细节是至关重要的。例如均衡学习率和从单位正态分布初始化权重。作者缩小L2距离对数以大致匹配初始化时的单位正态分布,并减少来自注意层的剩余增益。另外通过绑定键和查询矩阵,并应用权重衰减来进一步提高稳定性。

在综合网络G中,注意层与每个卷积块交错,利用样式向量w作为额外的标记。在每个注意块上,我们添加了一个单独的交叉注意机制 g c r o s s − a t t e n t i o n g_{cross-attention} gcrossattention来处理单个词嵌入。我们使用每个输入特征张量作为查询,文本嵌入作为注意机制的键和值。

3.3、生成器设计

3.3.1、文本和潜在空间条件映射

强大的语言模型对于产生强大的结果必不可少。作者对输入提示符进行标记化以产生条件向量 C ∈ R C × 1024 C∈R^{C×1024} CRC×1024,并从预训练好的CLIP特征提取器的倒数第二层提取特征。为了考虑额外的灵活性,模型在顶部应用额外的注意层T来处理词嵌入,然后将它们传递给基于mlp的映射网络: t = T ( E t x t ( c ) ) ∈ R C × 1024 \mathbf{t}=T\left(\mathcal{E}_{\mathrm{txt}}(\mathbf{c})\right) \in \mathbb{R}^{C \times 1024} t=T(Etxt(c))RC×1024,其中t的每一个分量ti都捕获了句子中第i个单词的嵌入。 t l o c a l = t 1 : C / E O T t_{local} = t_{{1:C}/EOT} tlocal=t1:C/EOT , t g l o b a l ∈ R 1024 t_{global}∈R^{1024} tglobalR1024,EOT指的是end of text,通过MLP映射网络处理这个全局文本描述符 t g l o b a l t_{global} tglobal以及潜在代码z ~ N(0,1),以提取样式 w = M ( z , t g l o b a l ) w = M(z, t_{global}) w=M(z,tglobal),全部过程为:

( t local  , t global  ) = T ( E t x t ( c ) ) , w = M ( z , t global  ) \begin{gathered}\left(\mathbf{t}_{\text {local }}, \mathbf{t}_{\text {global }}\right)=T\left(\mathcal{E}_{\mathrm{txt}}(\mathbf{c})\right), \\ \mathbf{w}=M\left(\mathbf{z}, \mathbf{t}_{\text {global }}\right)\end{gathered} (tlocal ,tglobal )=T(Etxt(c)),w=M(z,tglobal )

与原来的StyleGAN不同,模型既使用基于文本的样式代码w来调制合成网络eG,又使用词嵌入tlocal作为交叉注意的特征: x = G ~ ( w , t l o c a l ) x = \widetilde{G}(w,t_{local}) x=G (w,tlocal),文本图像对齐在视觉上随着交叉注意力的作用而改善。

3.3.2、网络

上图表示了生成器网络结构,灰色为卷积,黄色为自注意力层,蓝色为交叉注意力层,合成网络的具体过程用公式表述如下:

f ℓ + 1 = g xa  ℓ ( g attn  ℓ ( g adaconv  ℓ ( f ℓ , w ) , w ) , t local  ) \mathbf{f}_{\ell+1}=g_{\text {xa }}^{\ell}\left(g_{\text {attn }}^{\ell}\left(g_{\text {adaconv }}^{\ell}\left(\mathbf{f}_{\ell}, \mathbf{w}\right), \mathbf{w}\right), \mathbf{t}_{\text {local }}\right) f+1=gxa (gattn (gadaconv (f,w),w),tlocal )

其中g’xa、g’attn和g’adaconv表示交叉注意、自我注意和权重(反)调制层的第l层。

3.4、鉴别器设计

鉴别器由图像处理和文本处理两个分支组成。文本分支处理与生成器类似的文本。图像分支接收一个图像金字塔,并对每个图像尺度进行独立预测。此外,预测是在下采样层的所有后续尺度上进行的,使其成为一个多尺度输入,多尺度输出(MS-I/O)鉴别器。

鉴别器由使用条件文本函数 t D t_D tD处理文本和函数φ处理图像的独立分支组成。通过函数ψ比较两个分支的特征来预测真假。

3.4.1、文本处理

首先,为了将条件作用合并到鉴别器中,首先从文本c中提取文本描述符 t D t_D tD:与生成器类似,我们应用一个预先训练好的文本编码器,如CLIP,然后是几个可学习的注意层进行提取,这里只用到全局描述符,不再使用局部描述符。

3.4.2、多尺度图像处理

多尺度图像处理中,随着模型大小的增加,鉴别器网络的依赖于高分辨率层,早期低分辨率层变得不活跃。于是作者重新设计了模型架构,以提供跨多个尺度的训练信号。

为了在不同尺度上提取特征,作者定义了特征 ϕ i → j : R X i × X i × 3 → R X j D × X j D × C j \phi_{i \rightarrow j}: \mathbb{R}^{X_i \times X_i \times 3} \rightarrow \mathbb{R}^{X_j^D \times X_j^D \times C_j} ϕij:RXi×Xi×3RXjD×XjD×Cj,每个子网络 φ i → j φ_{i→j} φij都是全φ的子集, φ 0 → L φ_0→L φ0L,其中i > 0表示进入较晚,j < L表示退出较早。φ中的每一层都是由自我注意组成,然后以步长为2进行卷积。最后一层将空间范围压缩为1 × 1张量。这将产生 X j D {X^D_j} XjD ={32,16,8,4,1}的输出分辨率。这允许我们将金字塔上分辨率较低的图像注入中间层。由于我们在不同级别上使用共享的特征提取器,并且大多数添加的预测都是在低分辨率下进行的,因此增加的计算开销是可控的。

3.5、损失函数

3.5.1、多尺度输入,多尺度输出对抗损失

总的来说,我们的训练目标包括鉴别器损失,以及我们提出的匹配损失,以鼓励鉴别器考虑条件: V M S − I / O ( G , D ) = ∑ i = 0 L − 1 ∑ j = 1 L V G A N ( G i , D i j ) + V match  ( G i , D i j ) \mathcal{V}_{\mathrm{MS}-\mathrm{I} / \mathrm{O}}(G, D)=\sum_{i=0}^{L-1} \sum_{j=1}^L \mathcal{V}_{\mathrm{GAN}}\left(G_i, D_{i j}\right)+\mathcal{V}_{\text {match }}\left(G_i, D_{i j}\right) VMSI/O(G,D)=i=0L1j=1LVGAN(Gi,Dij)+Vmatch (Gi,Dij)

其中VGAN为标准的非饱和GAN损耗,为了计算鉴别器输出,我们训练预测器ψ,它使用文本特征 t D t_D tD来调制图像特征φ(x):
D i j ( x , c ) = ψ j ( ϕ i → j ( x i ) , t D ) + Conv ⁡ 1 × 1 ( ϕ i → j ( x i ) ) D_{i j}(\mathbf{x}, \mathbf{c})=\psi_j\left(\phi_{i \rightarrow j}\left(\mathbf{x}_i\right), \mathbf{t}_D\right)+\operatorname{Conv}_{1 \times 1}\left(\phi_{i \rightarrow j}\left(\mathbf{x}_i\right)\right) Dij(x,c)=ψj(ϕij(xi),tD)+Conv1×1(ϕij(xi))

ψ j ψ_j ψj实现为4层1×1调制卷积,并加入Conv1×1作为跳跃连接显式地维持一个无条件预测分支

3.5.2、Matching-aware损失

前面的GAN项测量图像x与条件c的匹配程度,以及x看起来有多逼真,而不考虑条件。然而,在早期的训练中,当伪影很明显时,鉴别器严重依赖于做出独立于条件反射的决定,并且在考虑后来的条件反射时犹豫不决。

为了强制判别器加入条件,我们将x与一个随机的、独立采样的条件c匹配,并将它们表示为一个假对:
V match  = E x , c , c ^ [ log ⁡ ( 1 + exp ⁡ ( D ( x , c ^ ) ) ) + log ⁡ ( 1 + exp ⁡ ( D ( G ( c ) , c ^ ) ) ] \begin{aligned} \mathcal{V}_{\text {match }}=\mathbb{E}_{\mathbf{x}, \mathbf{c}, \hat{\mathbf{c}}}[ & \log (1+\exp (D(\mathbf{x}, \hat{\mathbf{c}}))) \\ & +\log (1+\exp (D(G(\mathbf{c}), \hat{\mathbf{c}}))]\end{aligned} Vmatch =Ex,c,c^[log(1+exp(D(x,c^)))+log(1+exp(D(G(c),c^))]
其中(x, c)和c分别从pdata中采样。这种损失之前已经在文本到图像的GAN作品中研究过,除了我们发现对G生成的图像以及真实图像x强制Matchingaware损失,会导致性能的明显提高

3.5.3、CLIP对比损失

L CLIP  = E { c n } [ − log ⁡ exp ⁡ ( E img  ( G ( c 0 ) ) ⊤ E txt  ( c 0 ) ) ∑ n exp ⁡ ( E img  ( G ( c 0 ) ) ⊤ E txt  ( c n ) ) ] \left.\mathcal{L}_{\text {CLIP }}=\mathbb{E}_{\left\{\mathbf{c}_n\right\}}\left[-\log \frac{\exp \left(\mathcal{E}_{\text {img }}\left(G\left(\mathbf{c}_0\right)\right)^{\top} \mathcal{E}_{\text {txt }}\left(\mathbf{c}_0\right)\right)}{\sum_n \exp \left(\mathcal{E}_{\text {img }}\left(G\left(\mathbf{c}_0\right)\right)^{\top} \mathcal{E}_{\text {txt }}\left(\mathbf{c}_n\right)\right.}\right)\right] LCLIP =E{cn} lognexp(Eimg (G(c0))Etxt (cn)exp(Eimg (G(c0))Etxt (c0))

3.5.4、视觉辅助对抗性损失

综上所述,模型构建了一个附加的鉴别器,使用CLIP模型作为主干,称为视觉辅助GAN。我们冻结CLIP图像编码器,从中间层提取特征,并通过3 × 3 conv层的简单网络进行处理,从而进行真实/虚假预测。还通过调制结合了条件作用,如公式7所示。为了稳定训练,我们还添加了一个固定的随机投影层,正如投影GAN所提出的那样。称之为视觉辅助对抗性损失 L V i s i o n ( G ) L_{Vision(G)} LVision(G)

最终损失函数为: V ( G , D ) = V M S − I / O ( G , D ) + L C L I P ( G ) + L V i s i o n ( G ) V(G, D) = V_{MS-I/O}(G, D) +L_{CLIP}(G) + L_{Vision}(G) V(G,D)=VMSI/O(G,D)+LCLIP(G)+LVision(G)

四、实验

作者做了大量且全面的实验,看论文附录也很丰富。这里简单展示部分实验结果,具体请看原文。

4.1、消融实验

4.2、文本生成图像定量对比

4.3、与distilled diffusion models的对比

4.4、视觉效果


五、总结

GigaGAN架构为大规模生成模型开辟了一个全新的设计空间,并带回了关键的编辑功能,这些功能在向自回归和扩散模型过渡时变得具有挑战性。其已经测试的能力远远超出了用新方法可能实现的能力,并通过使用类似资源训练的自回归和扩散模型实现了具有竞争力的视觉质量,同时速度快了几个数量级,并实现了潜在的插值和程式化。

💡 最后

我们已经建立了🏤T2I研学社群,如果你还有其他疑问或者对🎓文本生成图像很感兴趣,可以私信我加入社群

📝 加入社群 抱团学习中杯可乐多加冰-深度学习T2I研习群

🔥 限时免费订阅文本生成图像T2I专栏

🎉 支持我:点赞👍+收藏⭐️+留言📝

有关Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择的更多相关文章

  1. ruby-on-rails - 仍然建议使用 Minitest 在 Rails 4 中测试路由吗? - 2

    在Rails3中,当在MiniTest中编写功能测试时,我养成了将路由测试与Controller操作分开测试的习惯。我从RailsGuideonTesting-Section9:TestingRoutes得到了这个想法.然而,在将我的应用程序升级到Rails4之后,我注意到如果我不为get|patch|post|delete方法提供一组适当的参数。例如,给定路线:#config/routes.rbnamespace"api"donamespace"v2",defaults:{format::json}doresources:usersdoresources:postsdoresourc

  2. ruby-on-rails - 在 RubyOnRails 应用程序中生成图形 - 2

    我想知道其他人发现哪些是Rails应用程序的最佳图形库/插件/gem等。当我说最好的时候,我想我的意思是易于实现和自定义图表的能力。我以前使用过openflashchart2并喜欢它的整体外观/效果,尽管根据需要自定义所有内容有时会很痛苦。您是否有经验或建议可以为我指明更好的方向?非常感谢。 最佳答案 对于本地生成的简单图表,请查看Gruff.还值得一看的是各种GoogleChartsruby​​库,googlecharts成为一个。 关于ruby-on-rails-在RubyOnRai

  3. 论文解读OTA: Optimal Transport Assignment for Object Detection - 2

    CSDN优秀解读:https://blog.csdn.net/jiaoyangwm/article/details/1266387752021https://arxiv.org/pdf/2103.14259.pdf关键解读在目标检测中标签分配的最新进展主要寻求为每个GT对象独立定义正/负训练样本。在本文中,我们创新性地从全局的角度重新审视标签分配,并提出将分配程序制定为一个最优传输(OT)问题——优化理论中一个被充分研究的课题。具体来说,我们将每个需求方(锚框)和供应商(GT标签)的单位传输成本定义为他们的分类和回归损失加权之和。在公式化后,找到最好的分配方案即为最小传播成本解决最优传输方案,

  4. Ruby String.encode 仍然给出 "invalid byte sequence in UTF-8" - 2

    在IRB中,我正在尝试以下操作:1.9.3p194:001>foo="\xBF".encode("utf-8",:invalid=>:replace,:undef=>:replace)=>"\xBF"1.9.3p194:002>foo.match/foo/ArgumentError:invalidbytesequenceinUTF-8from(irb):2:in`match'知道出了什么问题吗? 最佳答案 我猜"\xBF"已经认为它是用UTF-8编码的,所以当你调用encode时,它认为你正在尝试编码一个UTF-8中的UTF-8字符

  5. Two-Stream Convolutional Networks for Action Recognition in Videos双流网络论文精读 - 2

    Two-StreamConvolutionalNetworksforActionRecognitioninVideos双流网络论文精读论文:Two-StreamConvolutionalNetworksforActionRecognitioninVideos链接:https://arxiv.org/abs/1406.2199本文是深度学习应用在视频分类领域的开山之作,双流网络的意思就是使用了两个卷积神经网络,一个是SpatialstreamConvNet,一个是TemporalstreamConvNet。此前的研究者在将卷积神经网络直接应用在视频分类中时,效果并不好。作者认为可能是因为卷积神经

  6. 科研中论文常见数学符号及其含义(科研必备,建议收藏) - 2

    论文常见数学符号及其含义(科研必备)返回论文和资料目录数学符号在数学领域是非常重要的。在论文中,使用数学符号可以使得论文更加简洁明了,同时也能够准确地描述各种概念和理论。在本篇博客中,我将介绍一些常见的数学符号及其含义(省去特别简单的符号),希望能够帮助读者更好地理解数学论文。高等数学∑i=1nxi\sum_{i=1}^nx_i∑i=1n​xi​(求和符号):表示将x1,x2,…,xnx_1,x_2,\dots,x_nx1​,x2​,…,xn​中的所有数相加,例如∑i=1nxi\sum_{i=1}^nx_i∑i=1n​xi​表示将x1,x2,…,xnx_1,x_2,\dots,x_nx1​,x

  7. Ruby - 语句中不正确的换行符仍然会给出结果吗? - 2

    提炼出来的脚本如下:z1=(12-2)/(5)z2=(12-2)/(5)puts(z1.to_s+""+z2.to_s)给出:$rubyrubytest.rb2-1现在,我知道z1情况是正确的做法,因为行尾的悬挂运算符被解释为该行的自动延续。但是,我希望解释器在z2情况下快速失败,并告诉我该语句不完整,或者它的第二行是无意义的。但它处理得“很好”并给出“-1”答案。它是不是试图通过不承认自己感到困惑并希望胡说八道的答案被忽视来表现出自信?有人能解释一下z2的计算实际上发生了什么吗,为什么它是“-1”,为什么没有语法错误,并且有没有这个行为有用的例子(或者我们是否应该提出删除请求)?

  8. 论文笔记:InternImage—基于可变形卷积的视觉大模型,超越ViT视觉大模型,COCO 新纪录 64.5 mAP! - 2

    目录文章信息写在前面Background&MotivationMethodDCNV2DCNV3模型架构Experiment分类检测文章信息Title:InternImage:ExploringLarge-ScaleVisionFoundationModelswithDeformableConvolutionsPaperLink:https://arxiv.org/abs/2211.05778CodeLink:https://github.com/OpenGVLab/InternImage写在前面拿到文章之后先看了一眼在ImageNet1k上的结果,确实很高,超越了同等大小下的VAN、RepLK

  9. 手把手教你使用ChatGPT辅助写论文 - 2

    ChatGPT是一款引人注目的产品,它的突破性功能在各个领域都创造了巨大的需求。仅在发布后的两个月内,就累计了超过1亿的用户。它最突出的功能是能够在几秒钟内完成各种文案创作,包括论文、歌曲、诗歌、睡前故事和散文等。与流行的观点相反,ChatGPT可以做的不仅仅是为你写一篇文章,更有用的是它如何帮助指导您的写作过程和写作方法。接下来手把手教你利用ChatGPT辅助完成写作的五种方法。1.使用ChatGPT生成论文的观点在开始写作之前,我们需要让ChatGPT帮我们充实想法,找到论文切入点。当老师布置论文时,通常会给予学生一个提示,让他们可以自由地表达和分析。这时,我们需要找到论文的角度和思路,然

  10. ruby-on-rails - 是否仍然可以在 Rails 4 中使用测试单元? - 2

    从Rails3.2升级到Rails4后,我的应用程序可以运行,但是我用测试单元编写的测试是一场灾难。据传,Minitest与测试单元“兼容”。但是,如果我尝试使用(现在捆绑的)Minitest,就会有很多差异——从assert*语句名称和参数到(显然)许多其他既大又微妙的东西。如果我改为尝试避免Minitest并尝试将我的测试单元gem保留在我的Gemfile中,rake测试会爆炸,说,undefinedmethod'refute_predicate'forclass'ActiveSupport::TestCase'这是调用的结果require'rails/test_help':(我已

随机推荐