diff --git a/ui/src/app/jobs/new/SimpleJob.tsx b/ui/src/app/jobs/new/SimpleJob.tsx
index c9c4d0f8..2d9d9268 100644
--- a/ui/src/app/jobs/new/SimpleJob.tsx
+++ b/ui/src/app/jobs/new/SimpleJob.tsx
@@ -8,6 +8,7 @@ import { TextInput, SelectInput, Checkbox, FormGroup, NumberInput } from '@/comp
import Card from '@/components/Card';
import { X } from 'lucide-react';
import AddSingleImageModal, { openAddImageModal } from '@/components/AddSingleImageModal';
+import {FlipHorizontal2, FlipVertical2} from "lucide-react"
type Props = {
jobConfig: JobConfig;
@@ -638,6 +639,18 @@ export default function SimpleJob({
/>
)}
+
+ Flip X >}
+ checked={dataset.flip_x || false}
+ onChange={value => setJobConfig(value, `config.process[0].datasets[${i}].flip_x`)}
+ />
+ Flip Y >}
+ checked={dataset.flip_y || false}
+ onChange={value => setJobConfig(value, `config.process[0].datasets[${i}].flip_y`)}
+ />
+
diff --git a/ui/src/app/jobs/new/jobConfig.ts b/ui/src/app/jobs/new/jobConfig.ts
index 8b0c28a4..df257bb9 100644
--- a/ui/src/app/jobs/new/jobConfig.ts
+++ b/ui/src/app/jobs/new/jobConfig.ts
@@ -16,6 +16,8 @@ export const defaultDatasetConfig: DatasetConfig = {
shrink_video_to_frames: true,
num_frames: 1,
do_i2v: true,
+ flip_x: false,
+ flip_y: false,
};
export const defaultJobConfig: JobConfig = {
diff --git a/ui/src/components/formInputs.tsx b/ui/src/components/formInputs.tsx
index 9dacc336..5626a7b4 100644
--- a/ui/src/components/formInputs.tsx
+++ b/ui/src/components/formInputs.tsx
@@ -201,7 +201,7 @@ export const SelectInput = (props: SelectInputProps) => {
};
export interface CheckboxProps {
- label?: string;
+ label?: string | React.ReactNode;
checked: boolean;
onChange: (checked: boolean) => void;
className?: string;
diff --git a/ui/src/docs.tsx b/ui/src/docs.tsx
index 3e8359eb..6b414488 100644
--- a/ui/src/docs.tsx
+++ b/ui/src/docs.tsx
@@ -90,6 +90,20 @@ const docs: { [key: string]: ConfigDoc } = {
>
),
},
+ 'datasets.flip': {
+ title: 'Flip X and Flip Y',
+ description: (
+ <>
+ You can augment your dataset on the fly by flipping the x (horizontal) and/or y (vertical) axis. Flipping a single axis will effectively double your dataset.
+ It will result it training on normal images, and the flipped versions of the images. This can be very helpful, but keep in mind it can also
+ be destructive. There is no reason to train people upside down, and flipping a face can confuse the model as a person's right side does not
+ look identical to their left side. For text, obviously flipping text is not a good idea.
+
+
+ Control images for a dataset will also be flipped to match the images, so they will always match on the pixel level.
+ >
+ ),
+ },
'train.unload_text_encoder': {
title: 'Unload Text Encoder',
description: (
diff --git a/ui/src/types.ts b/ui/src/types.ts
index d7da45b9..5034d4f9 100644
--- a/ui/src/types.ts
+++ b/ui/src/types.ts
@@ -87,6 +87,8 @@ export interface DatasetConfig {
num_frames: number;
shrink_video_to_frames: boolean;
do_i2v: boolean;
+ flip_x: boolean;
+ flip_y: boolean;
}
export interface EMAConfig {