# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T11:52:23.341580Z","iopub.execute_input":"2025-12-17T11:52:23.341853Z","iopub.status.idle":"2025-12-17T11:52:28.244852Z","shell.execute_reply.started":"2025-12-17T11:52:23.341822Z","shell.execute_reply":"2025-12-17T11:52:28.244035Z"}}
# !pip install --force-reinstall protobuf==3.20.3


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T11:52:28.247073Z","iopub.execute_input":"2025-12-17T11:52:28.247411Z","iopub.status.idle":"2025-12-17T11:52:28.252992Z","shell.execute_reply.started":"2025-12-17T11:52:28.247372Z","shell.execute_reply":"2025-12-17T11:52:28.252262Z"}}
import os
os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'python'


# %% [markdown]
# # Data Loading

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:47.868297Z","iopub.execute_input":"2025-12-17T08:00:47.868515Z","iopub.status.idle":"2025-12-17T08:00:47.901451Z","shell.execute_reply.started":"2025-12-17T08:00:47.868499Z","shell.execute_reply":"2025-12-17T08:00:47.900676Z"}}
import numpy as np
import pandas as pd

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:47.931403Z","iopub.execute_input":"2025-12-17T08:00:47.931628Z","iopub.status.idle":"2025-12-17T08:00:47.943764Z","shell.execute_reply.started":"2025-12-17T08:00:47.931611Z","shell.execute_reply":"2025-12-17T08:00:47.943208Z"}}
train = pd.read_csv('/kaggle/input/csiro-biomass/train.csv')
test = pd.read_csv('/kaggle/input/csiro-biomass/test.csv')

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:47.944762Z","iopub.execute_input":"2025-12-17T08:00:47.944962Z","iopub.status.idle":"2025-12-17T08:00:47.955497Z","shell.execute_reply.started":"2025-12-17T08:00:47.944931Z","shell.execute_reply":"2025-12-17T08:00:47.954913Z"}}
train.head()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:47.997313Z","iopub.execute_input":"2025-12-17T08:00:47.997746Z","iopub.status.idle":"2025-12-17T08:00:48.002304Z","shell.execute_reply.started":"2025-12-17T08:00:47.997728Z","shell.execute_reply":"2025-12-17T08:00:48.001708Z"}}
train.shape

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.003402Z","iopub.execute_input":"2025-12-17T08:00:48.003592Z","iopub.status.idle":"2025-12-17T08:00:48.015864Z","shell.execute_reply.started":"2025-12-17T08:00:48.003578Z","shell.execute_reply":"2025-12-17T08:00:48.015171Z"}}
del train['sample_id']

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.016604Z","iopub.execute_input":"2025-12-17T08:00:48.016837Z","iopub.status.idle":"2025-12-17T08:00:48.029766Z","shell.execute_reply.started":"2025-12-17T08:00:48.016818Z","shell.execute_reply":"2025-12-17T08:00:48.029016Z"}}
colum = train.columns

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.031415Z","iopub.execute_input":"2025-12-17T08:00:48.031652Z","iopub.status.idle":"2025-12-17T08:00:48.044271Z","shell.execute_reply.started":"2025-12-17T08:00:48.031636Z","shell.execute_reply":"2025-12-17T08:00:48.043487Z"}}
colum = [ 'Sampling_Date', 'State', 'Species', 'Pre_GSHH_NDVI',
       'Height_Ave_cm']

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.045132Z","iopub.execute_input":"2025-12-17T08:00:48.045470Z","iopub.status.idle":"2025-12-17T08:00:48.059781Z","shell.execute_reply.started":"2025-12-17T08:00:48.045449Z","shell.execute_reply":"2025-12-17T08:00:48.059225Z"}}
train = train.drop(columns=colum,axis=1)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.060575Z","iopub.execute_input":"2025-12-17T08:00:48.060863Z","iopub.status.idle":"2025-12-17T08:00:48.077152Z","shell.execute_reply.started":"2025-12-17T08:00:48.060840Z","shell.execute_reply":"2025-12-17T08:00:48.076575Z"}}
train.head()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.077888Z","iopub.execute_input":"2025-12-17T08:00:48.078348Z","iopub.status.idle":"2025-12-17T08:00:48.095747Z","shell.execute_reply.started":"2025-12-17T08:00:48.078331Z","shell.execute_reply":"2025-12-17T08:00:48.095155Z"}}
train = train.pivot_table(
    index="image_path",
    columns="target_name",
    values="target"
).reset_index()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.096508Z","iopub.execute_input":"2025-12-17T08:00:48.096782Z","iopub.status.idle":"2025-12-17T08:00:48.106228Z","shell.execute_reply.started":"2025-12-17T08:00:48.096760Z","shell.execute_reply":"2025-12-17T08:00:48.105441Z"}}
train.head()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.106951Z","iopub.execute_input":"2025-12-17T08:00:48.107658Z","iopub.status.idle":"2025-12-17T08:00:48.119257Z","shell.execute_reply.started":"2025-12-17T08:00:48.107635Z","shell.execute_reply":"2025-12-17T08:00:48.118596Z"}}
target_cols = [
    "Dry_Clover_g",
    "Dry_Dead_g",
    "Dry_Green_g",
    "Dry_Total_g",
    "GDM_g"
]

train = train[["image_path"] + target_cols]


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.122851Z","iopub.execute_input":"2025-12-17T08:00:48.123076Z","iopub.status.idle":"2025-12-17T08:00:48.137461Z","shell.execute_reply.started":"2025-12-17T08:00:48.123061Z","shell.execute_reply":"2025-12-17T08:00:48.136720Z"}}
train.shape

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.138136Z","iopub.execute_input":"2025-12-17T08:00:48.138461Z","iopub.status.idle":"2025-12-17T08:00:48.149185Z","shell.execute_reply.started":"2025-12-17T08:00:48.138444Z","shell.execute_reply":"2025-12-17T08:00:48.148445Z"}}
# !pip install protobuf
# !pip uninstall protobuf -y


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.149829Z","iopub.execute_input":"2025-12-17T08:00:48.150020Z","iopub.status.idle":"2025-12-17T08:00:48.162252Z","shell.execute_reply.started":"2025-12-17T08:00:48.149998Z","shell.execute_reply":"2025-12-17T08:00:48.161630Z"}}
# import os
# os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T11:47:36.549407Z","iopub.execute_input":"2025-12-17T11:47:36.549687Z","iopub.status.idle":"2025-12-17T11:47:36.555363Z","shell.execute_reply.started":"2025-12-17T11:47:36.549660Z","shell.execute_reply":"2025-12-17T11:47:36.554638Z"}}
# from tensorflow import keras
from keras.preprocessing.image import load_img, img_to_array
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten
from sklearn.model_selection import train_test_split


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.187754Z","iopub.execute_input":"2025-12-17T08:00:48.188008Z","iopub.status.idle":"2025-12-17T08:00:48.201749Z","shell.execute_reply.started":"2025-12-17T08:00:48.187986Z","shell.execute_reply":"2025-12-17T08:00:48.201161Z"}}
train_df, valid_df = train_test_split(train,test_size=0.2,random_state=42)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.202484Z","iopub.execute_input":"2025-12-17T08:00:48.202808Z","iopub.status.idle":"2025-12-17T08:00:48.215710Z","shell.execute_reply.started":"2025-12-17T08:00:48.202791Z","shell.execute_reply":"2025-12-17T08:00:48.215186Z"}}
train_df = train_df.reset_index(drop=True)
valid_df   = valid_df.reset_index(drop=True)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.216308Z","iopub.execute_input":"2025-12-17T08:00:48.216559Z","iopub.status.idle":"2025-12-17T08:00:48.230717Z","shell.execute_reply.started":"2025-12-17T08:00:48.216542Z","shell.execute_reply":"2025-12-17T08:00:48.230019Z"}}
IMG_SIZE = (224,224)

def load_image(path):
    img = load_img(path,target_size=IMG_SIZE)
    img = img_to_array(img)/255.0
    return img

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.231459Z","iopub.execute_input":"2025-12-17T08:00:48.231695Z","iopub.status.idle":"2025-12-17T08:00:48.244847Z","shell.execute_reply.started":"2025-12-17T08:00:48.231680Z","shell.execute_reply":"2025-12-17T08:00:48.244077Z"}}
path = "/kaggle/input/csiro-biomass/"
def train_generator(df, batch_size=16):
    while True:
        df = df.sample(frac=1).reset_index(drop=True)
        for i in range(0, len(df), batch_size):
            batch_df = df.iloc[i:i+batch_size]

            images = []
            targets = []

            for _, row in batch_df.iterrows():
                images.append(load_image(path + row["image_path"]))
                targets.append(row[target_cols].values.astype(np.float32))

            yield np.array(images, dtype=np.float32), np.array(targets, dtype=np.float32)


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.245611Z","iopub.execute_input":"2025-12-17T08:00:48.245851Z","iopub.status.idle":"2025-12-17T08:00:48.257303Z","shell.execute_reply.started":"2025-12-17T08:00:48.245827Z","shell.execute_reply":"2025-12-17T08:00:48.256592Z"}}
def val_generator(df, batch_size=16):
    while True:
        for i in range(0, len(df), batch_size):
            batch_df = df.iloc[i:i+batch_size]

            images = []
            targets = []

            for _, row in batch_df.iterrows():
                images.append(load_image(path + row["image_path"]))
                targets.append(row[target_cols].values.astype(np.float32))

            yield np.array(images, dtype=np.float32), np.array(targets, dtype=np.float32)


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:48.258114Z","iopub.execute_input":"2025-12-17T08:00:48.258340Z","iopub.status.idle":"2025-12-17T08:00:50.153856Z","shell.execute_reply.started":"2025-12-17T08:00:48.258320Z","shell.execute_reply":"2025-12-17T08:00:50.153314Z"}}
model = Sequential()

model.add(Conv2D(32,kernel_size=(3,3),activation='relu',input_shape=(224,224,3)))
model.add(MaxPooling2D(pool_size=(2,2),strides=2,padding='valid'))

model.add(Conv2D(64,kernel_size=(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2),strides=2,padding='valid'))

model.add(Conv2D(128,kernel_size=(3,3),activation='relu'))
model.add(MaxPooling2D(pool_size=(2,2),strides=2,padding='valid'))


model.add(Flatten())

model.add(Dense(32,activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(64,activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(128,activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(5,activation='linear'))

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.154647Z","iopub.execute_input":"2025-12-17T08:00:50.154906Z","iopub.status.idle":"2025-12-17T08:00:50.176172Z","shell.execute_reply.started":"2025-12-17T08:00:50.154885Z","shell.execute_reply":"2025-12-17T08:00:50.175638Z"}}
model.summary()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.176768Z","iopub.execute_input":"2025-12-17T08:00:50.177032Z","iopub.status.idle":"2025-12-17T08:00:50.189110Z","shell.execute_reply.started":"2025-12-17T08:00:50.177010Z","shell.execute_reply":"2025-12-17T08:00:50.188428Z"}}
model.compile(optimizer='adam',loss='mse',metrics=['mae'])

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.189852Z","iopub.execute_input":"2025-12-17T08:00:50.190172Z","iopub.status.idle":"2025-12-17T08:00:50.696512Z","shell.execute_reply.started":"2025-12-17T08:00:50.190156Z","shell.execute_reply":"2025-12-17T08:00:50.695895Z"}}
BATCH_SIZE = 16
EPOCHS = 10

# model.fit(
#     train_generator(train_df, BATCH_SIZE),
#     steps_per_epoch=max(1, len(train_df) // BATCH_SIZE),
#     validation_data=val_generator(valid_df, BATCH_SIZE),
#     validation_steps=max(1, len(valid_df) // BATCH_SIZE),
#     epochs=EPOCHS
# )

from keras.models import load_model
model = load_model("/kaggle/input/cnn-model1/keras/default/1/cnn-model1.keras")

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.697321Z","iopub.execute_input":"2025-12-17T08:00:50.697565Z","iopub.status.idle":"2025-12-17T08:00:50.701122Z","shell.execute_reply.started":"2025-12-17T08:00:50.697544Z","shell.execute_reply":"2025-12-17T08:00:50.700368Z"}}
# model.save("cnn-model1.keras")

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.701847Z","iopub.execute_input":"2025-12-17T08:00:50.702076Z","iopub.status.idle":"2025-12-17T08:00:50.717984Z","shell.execute_reply.started":"2025-12-17T08:00:50.702049Z","shell.execute_reply":"2025-12-17T08:00:50.717459Z"}}
test_images = (
    test[["image_path"]]
    .drop_duplicates()
    .reset_index(drop=True)
)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.718736Z","iopub.execute_input":"2025-12-17T08:00:50.719579Z","iopub.status.idle":"2025-12-17T08:00:50.732938Z","shell.execute_reply.started":"2025-12-17T08:00:50.719561Z","shell.execute_reply":"2025-12-17T08:00:50.732395Z"}}
test_images.head()

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.733635Z","iopub.execute_input":"2025-12-17T08:00:50.733868Z","iopub.status.idle":"2025-12-17T08:00:50.746384Z","shell.execute_reply.started":"2025-12-17T08:00:50.733849Z","shell.execute_reply":"2025-12-17T08:00:50.745783Z"}}
path

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.749120Z","iopub.execute_input":"2025-12-17T08:00:50.749605Z","iopub.status.idle":"2025-12-17T08:00:50.862274Z","shell.execute_reply.started":"2025-12-17T08:00:50.749588Z","shell.execute_reply":"2025-12-17T08:00:50.861691Z"}}
X_test = np.array(
    [load_image(path+p) for p in test_images["image_path"]],
    dtype=np.float32
)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.863039Z","iopub.execute_input":"2025-12-17T08:00:50.863306Z","iopub.status.idle":"2025-12-17T08:00:50.867958Z","shell.execute_reply.started":"2025-12-17T08:00:50.863280Z","shell.execute_reply":"2025-12-17T08:00:50.867293Z"}}
def test_generator(df, batch_size=8):
    for i in range(0, len(df), batch_size):
        batch_df = df.iloc[i:i+batch_size]
        images = [load_image(path + p) for p in batch_df["image_path"]]
        yield (np.array(images, dtype=np.float32),)


# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:50.868666Z","iopub.execute_input":"2025-12-17T08:00:50.868882Z","iopub.status.idle":"2025-12-17T08:00:52.189441Z","shell.execute_reply.started":"2025-12-17T08:00:50.868867Z","shell.execute_reply":"2025-12-17T08:00:52.188798Z"}}
preds = model.predict(
    test_generator(test_images, BATCH_SIZE),
    steps=int(np.ceil(len(test_images)/BATCH_SIZE))
)

# %% [code] {"execution":{"iopub.status.busy":"2025-12-17T08:00:52.190467Z","iopub.execute_input":"2025-12-17T08:00:52.190712Z","iopub.status.idle":"2025-12-17T08:00:52.312783Z","shell.execute_reply.started":"2025-12-17T08:00:52.190695Z","shell.execute_reply":"2025-12-17T08:00:52.312187Z"}}
# FINAL SUBMISSION CELL - Replace your current one completely
import pandas as pd
import numpy as np
import os

# Load sample submission FIRST (defines exact format)
sample = pd.read_csv("/kaggle/input/csiro-biomass/sample_submission.csv")
print("Sample shape:", sample.shape)
print("Sample columns:", sample.columns.tolist())

# Generate predictions ONCE (your generator works)
test_preds = model.predict(
    test_generator(test_images, batch_size=8),
    steps=int(np.ceil(len(test_images) / 8)),
    verbose=1
)

# Create predictions DataFrame
pred_df = pd.DataFrame(test_preds, columns=target_cols)
pred_df['image_path'] = test_images['image_path'].values  # Match lengths exactly

# Create long format matching sample_submission structure
submission = pred_df.melt(
    id_vars='image_path',
    value_vars=target_cols,
    var_name='target_name',
    value_name='target'
)

# Generate sample_id exactly like sample_submission
submission['sample_id'] = (
    submission['image_path'].str.split('/').str[-1]
    .str.replace('.jpg', '', regex=False) + '__' + 
    submission['target_name']
)

# Reorder columns to match sample_submission exactly
submission = submission[['sample_id', 'target']]

# VALIDATION CHECKS
assert len(submission) == len(sample), f"Row mismatch: {len(submission)} vs {len(sample)}"
assert list(submission.columns) == list(sample.columns), "Column mismatch"
assert submission.isna().sum().sum() == 0, "NaNs found!"

# Save to EXACT correct path
submission.to_csv('/kaggle/working/submission.csv', index=False)

# FINAL VERIFICATION
print("Files:", os.listdir('/kaggle/working/'))
print("Submission shape:", pd.read_csv('/kaggle/working/submission.csv').shape)
print("Submission head:")
print(pd.read_csv('/kaggle/working/submission.csv').head())
print("✅ Submission ready!")

